zoukankan      html  css  js  c++  java
  • WPF如何获得变量异步回调函数时产生的异步回调

      有这样的问题,WPF当使用异步回调,需要使用产生的异步变量中的回调函数。数据库中查询诸如异步函数来获得一DataTable。怎样传递给回调函数呢?

    【方案一】使用全局变量

      非常easy想到的是用全局变量。这也是最简单的办法。可是假设我想循环调用呢,比如回调函数推断异步函数运行完之后的DataTable有没有数据,有数据则继续异步(BeginInvoke),这时候假设使用全局变量可能会出现意外情况,由于是循环调用,回调函数使用的DataTable是不是你想要的那个值就比較难说了。

    【方案二】闭包

      这也是一个比較常规的办法,闭包的话就方便内部变量传递了,写法例如以下:

    复制代码
    private void QueryDateBase()
            {
                DataTable dtTarget = new DataTable();//共享变量
    
                Action handler = delegate()//异步匿名托付
                {
                    dtTarget = XXX查询数据库;
                };
                
                AsyncCallback functionCallBack = delegate(IAsyncResult asyResult)//回调匿名托付
                {
                    handler.EndInvoke(asyResult);
                    if (dtTarget.Rows.Count > 0)
                    {
                        QueryDateBase();
                    }
                };
    
                handler.BeginInvoke(functionCallBack, null);
            }
    复制代码
      这就是所谓的闭包了,使用了匿名托付,回调函数和异步函数定义在一个方法体内。这样变量就能共享,类似的。WPF的动画有个Completed事件,假设它里面要使用到開始运行时的一些变量,也能使用此法共享变量。

    这里有两点要注意:

    1. handler注冊的方法里不能涉及到不论什么UI控件和UI逻辑。否则异步方法没有调用完就会运行EndInvoke方法,导致调用错误
    2. 假设必需要用到UI控件或者UI逻辑,能够用Application.Current.Dispatcher.Invoke(new Action(() => { ...}));

      那么,能不能不使用全局变量呢?

    【方案三】使用返回值

      使用带返回值的托付。这样在托付EndInvoke的时候就能够获得托付的返回值了,代码看起来是这种:

    复制代码
        public class Student
        {
            public Func<DataTable> queryHandler;
    
            public Student()
            {
                queryHandler = QueryDateBase;
                queryHandler.BeginInvoke(CallBack, null);
            }
    
            private DataTable QueryDateBase()
            {
                DataTable dtTarget = XXX查数据库;
                return dtTarget;
            }
    
            private void CallBack(IAsyncResult ar)
            {
                DataTable dtCallBack = queryHandler.EndInvoke(ar);
                if (dtCallBack.Rows.Count > 0)
                {
                    queryHandler.BeginInvoke(CallBack, null);
                }
            }
        }
    复制代码
      个人觉得这是比較正统的写法。精准的返回值,没有全局变量。事实上Winform也是如此,使用起来并无差异。仅仅是wpf涉及UI时要注意。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    python 计时累积超过24小时时继续往上累加
    linux 下获取文件最后几行
    unbuntu 安装python包提示E: Unable to locate package python-timeout
    python 计时器
    jquery中html()、text()、val()的区别
    DESC和 ACS
    jQuery自动截取文字长度,超过部分
    Spring MVC 注解
    注解笔记
    Spring Data JPA初使用 *****重要********
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4885180.html
Copyright © 2011-2022 走看看