最近在做一个Windows Mobile平台客户端的项目,需要在后台线程中连接服务器并进行消息的发送和接收。
后台任务
由于之前也没接触过C#,所以查找了一下相关资料,发现基本上有使用BackgroundWorker和直接使用Thread两种实现方式。
BackgroundWorker看名字应该类似于Android平台中AsynTask,为了方便编写简单的非UI后台任务而对Thread进行了封装。由于之前的Android客户端中收发消息都是使用的AsynTask,并且后台任务的逻辑也比较简单,BackgroundWorker完全能够满足要求。
写代码时发现没有找到BackgroundWorker这个类,想到Windows Mobile平台使用的是.NET Compact Framework,江湖人称.NET CF,Google了一下,果然CF是不支持BackgroundWorker的,只好另寻他法。
Google之后发现已经有人问过这个问题:
回答中有人建议自己写一个BackgroundWorker,也有人建议参考微软官方的这篇文章:
这篇文章中提到了在.NET CF中创建后台任务的三种方式:
- 异步访问Web Service
- 线程池
- 显示的创建线程
根据我们的应用场景我最终选择了线程池这种比较简单的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
查看默认的线程池中辅助线程的最大数目和异步I/O线程的最大数目:
1 2 3 4 |
|
可以使用ThreadPool.SetMaxThreads
方法按需修改。
在后台任务中操纵UI控件
将消息收发转到后台线程之后,就不能直接在收发消息时直接操纵UI控件了,需要在UI线程中定义好操纵控件的方法,然后在后台线程中使用Control.Invoke
或者Control.BeginInvoke
方法通过委托的方式进行调用,Invoke
与BeginInvoke
的区别是前者在进行委托调用时后台线程会阻塞,而后者使用的是异步委托调用。详细分析可以参考这几篇博文:
- http://www.cnblogs.com/mashang/archive/2009/08/01/1536730.html
- http://blog.csdn.net/ansencumt/article/details/6024775
关于WaitCursor
在Android中执行后台任务时,我们通常会在界面上覆盖一个指示后台任务正在运行的ProgressDialog。
C#中可以使用Cursor.Current = Cursors.WaitCursor;
来显示一个等待指示器。但是这时我们依然可以对界面中的控件进行操作,简单的解决方法是后台任务开始时使用this.Enabled = false;
将当前窗体设为不可用,执行结束后this.Enabled = true;
再恢复可用。缺点是整个界面会变成灰色。