在C++中有2种类型的线程:UI Thread和Worker Thread,前者是基于用户界面的有消息循环的线程、后者是没有用户界面的侧重于大时空运算的线程。直接调用Windows相关线程及同步对象的API即可。

在.NET framework进阶编程中,可以用基于delegate的方式来处理界面保持活动,而后台作大运算量或耗时的操作。

应用程序的需求是:点击一个按钮来刷新用户界面上某区域数据相关控件,其内容动态从web service上获取并填充到该控件,而不影响另一区域实时显示数据。

基本的作法是这样的:
1,定义2个delegate及分别对应的处理过程,注意返值和参数要一一对应。一个delegate代表的函数是顶层的异步调用,它会调用另外一个delegate,而另一个delegate代表的函数过程是GUI上会被刷新内容的控件相关的操作,通过System.Control.InvokeRequired判断调用线程与被调用控件是否在同一线程来显式运行System.Control.Invoke(明显地,它们位于不同线程,主要的目的是让同步调用可以复用这段函数代码)。需要特别注意的是,耗时操作要从System.Control.Invoke调用的delegate中分离开,否则跟单线程时效果没有区别,这一点让我困扰了不少时间。
2,定义一个回调函数,用于异步操作结束后的回调(而不是通过调用IAsyncResult接口的轮询方式),里面包括按钮控件的使能恢复和结束异步调用的EndInvoke显示调用。它是位于不同于调用线程的线程池中。

关键代码段如下:

        private void UpdateInquiry()
{ //UI界面的更新放在这里(the other thread) //control operations on GUI such as clear, load data, fresh etc.
...
} private delegate void crossThreadDelegate();
private void UpdateInquiryContainer() //此函数也可用于同步调用
{
//耗时操作一定要放在这里,不要包含在UpdateInquiry(UI界面的更新)中!!!(just like a worker thread as windows API)
this._presenter.TimeConsumingOperation(); if (treeListInquired.InvokeRequired)
{
crossThreadDelegate caller = new crossThreadDelegate(UpdateInquiry);
treeListInquired.Invoke(caller);
}
else
{
UpdateInquiry();
}
} //callback function which is used to end the asynchronous inquiry operation and resume the
//enable state of related controls
public void AsyncRefreshCallback(IAsyncResult result)
{
AsyncRefreshCaller inquiryDelegate = (AsyncRefreshCaller)((AsyncResult)result).AsyncDelegate;
inquiryDelegate.EndInvoke(result); //enable related controls again - there may be an issue thread-safe-related - by OY
if (bCanDemand)
{
dateTimePickerDate.Enabled = true;
btnPrev.Enabled = true;
btnNext.Enabled = true;
btnRefresh.Enabled = true;
}
} private delegate void AsyncRefreshCaller();
private void RefreshInquiry()
{
//disable related controls on GUI
dateTimePickerDate.Enabled = false;
btnPrev.Enabled = false;
btnNext.Enabled = false;
btnRefresh.Enabled = false; //invoke synchronous method asynchronously
AsyncRefreshCaller inquiryDelegate = new AsyncRefreshCaller(UpdateInquiryContainer);
AsyncCallback callback = new AsyncCallback(this.AsyncRefreshCallback);
inquiryDelegate.BeginInvoke(callback, null);
//inquiryDelegate.BeginInvoke(null, null);
}

参考:MSDN(VS2005) - ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxadvance/html/c6baed9f-2a25-4728-9a9a-53b7b14840cf.htm

最新文章

  1. Zabbix基本配置及监控主机
  2. 【chrome插件】web版微信接入图灵机器人API实现自动回复
  3. x名称空间
  4. 【腾讯优测干货分享】如何降低App的待机内存(五)——优化dex相关内存及本章总结
  5. 获取C++类成员变量的地址偏移
  6. HTML5 QQ登录背景动态图片
  7. assert 实现分析
  8. Python开发之路
  9. 2-SAT 问题与解法小结
  10. TCP为什么不是两次握手而是三次?
  11. vue 移动端公众号采坑经验
  12. python note 11 函数名的使用、闭包、迭代器
  13. 推荐数据库、Web、Net、架构的PDF数据,书不在多,在看!
  14. Object_C 与JavaScript交互使用总结
  15. php创建桌面快捷方式实现方法
  16. Hmtl5 <input>中placeholder属性(新属性)
  17. pthread调度策略,优先级和竞争范围
  18. SpringCloud之服务注册-eureka
  19. Mac 10.12安装Git管理工具SourceTree
  20. poi 取excel单元格内容时,需要判断单元格的类型,才能正确取出

热门文章

  1. iOS.XcodeUsage
  2. 清晰易懂!关于PS入门的超详细笔记!
  3. Https如何确保传输安全的
  4. flask 中文编码解码
  5. eclipse构建maven的web项目(转载)
  6. 使用ServiceDesk Plus保证及时解决问题,防止违反SLA
  7. Linux运维之Ansible自动化运维管理工具
  8. List<T>中,Remove和RemoveAt区别
  9. 树莓派无法挂载exfat格式硬盘
  10. 23.Xcode中常用的快捷键操作