WPF异步回调时回调函数如何获取异步函数产生的变量
2014-10-13 14:55
323 查看
有这么一个问题,WPF在使用异步回调的时候,回调函数需要用到异步函数里产生的一个变量,例如异步函数里查询数据库得到了一个DataTable,如何传递给回调函数呢?
【方案一】使用全局变量
很容易想到的是用全局变量,这也是最简单的办法。但是如果我想循环调用呢,例如回调函数判断异步函数执行完之后的DataTable有没有数据,有数据则继续异步(BeginInvoke),这时候如果使用全局变量可能会出现意外情况,因为是循环调用,回调函数使用的DataTable是不是你想要的那个值就比较难说了。
【方案二】闭包
这也是一个比较常规的办法,闭包的话就方便内部变量传递了,写法如下:
这就是所谓的闭包了,使用了匿名委托,回调函数和异步函数定义在一个方法体内,这样变量就能共享,类似的,WPF的动画有个Completed事件,如果它里面要使用到开始执行时的一些变量,也能使用此法共享变量。这里有两点要注意:
handler注册的方法里不能涉及到任何UI控件和UI逻辑,否则异步方法没有调用完就会执行EndInvoke方法,导致调用错误
如果必须要用到UI控件或者UI逻辑,可以用Application.Current.Dispatcher.Invoke(new Action(() => { ...}));
那么,能不能不使用全局变量呢?
【方案三】使用返回值
使用带返回值的委托,这样在委托EndInvoke的时候就可以获得委托的返回值了,代码看起来是这样的:
个人认为这是比较正统的写法,精准的返回值,没有全局变量。其实Winform也是如此,使用起来并无差异,只是wpf涉及UI时要注意。
【方案一】使用全局变量
很容易想到的是用全局变量,这也是最简单的办法。但是如果我想循环调用呢,例如回调函数判断异步函数执行完之后的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事件,如果它里面要使用到开始执行时的一些变量,也能使用此法共享变量。这里有两点要注意:
handler注册的方法里不能涉及到任何UI控件和UI逻辑,否则异步方法没有调用完就会执行EndInvoke方法,导致调用错误
如果必须要用到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时要注意。
相关文章推荐
- WPF异步回调时回调函数如何获取异步函数产生的变量
- WPF如何获得变量异步回调函数时产生的异步回调
- WPF异步回调时回调函数如何获取
- node.js如何获取request模块中异步函数回调的返回值
- 如何按照顺序执行异步ajax的回调函数
- 如何将后台返回的值传给回调函数之外的变量
- JavaScript是单线程运行的,但是ajax是如何实现的异步函数回调的?
- 如何把类函数做为回调函数.--提出问题
- 请问如何可以获取代码中函数与函数的调用关系.
- Django 中自定义 tag 如何获取变量参数的值
- 获取变量类型的函数
- 如何将类成员函数作成一个回调函数
- 在编辑状态下变量或函数不能显示提示时如何打开提示功能(或编程助手)
- 如何让API回调你的VC类成员函数而不是静态函数
- WPF开发中遇到的问题及解决系列(三):如何改变ListView 中各行的背景色(背景色产生交替效果)
- 如何在类中实现回调成员函数
- ACTIVEX DLL时,如何在回调函数中改变DLL的一些私有变量的值,并触发用户事件?
- 如何访问私有成员变量和函数
- PHP获取当前url的函数及服务器变量
- Ajax中如何使用Session变量,Cookies可以用表单验证的方式获取并使用。