C#笔记之 跨线程通信解决方案
2018-03-27 10:26
141 查看
C# 跨线程通信解决方案
Android和C#之间来回跑是真的累,虽然两者语法有很多相似的地方,Adnroid跨线程通信还是有很多方案的,Handler用得最多,C#也不例外,以下算是自己根据网上的资料结合自己在项目中使用情况的总结:1、 最简单粗暴的
在相应窗体的构造方法里面加入下面一句代码:Control.CheckForIllegalCrossThreadCalls = false;
意思就是编译运行时不检查线程之间访问的冲突,子线程可以随时更新UI,虽然很方便,但是安全性却很低,很容易造成数据的不一致性,比如你子线程A更新了某个控件的值,此时线程B又去更新了这个控件的值 ,这就不能保证事物的一致性,后果很严重!所以还是不建议使用,也不明白微软为啥还保留这个。
2、利用delegate和invoke
//声明一个委托 private delegate void DelegateClick(/**参数列表*/); //委托执行的方法 private void initUI(/**参数列表*/){ if (/*你要更新的控件 比如Label*/ label1.InvokeRequired) { // 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它 DelegateClick mDele=new DelegateClick(initUI); this.label1.Invoke(mDele, new object[] { /*参数*/}); } else { this.label1.Text = /*参数*/; } } public Form(){ ...... //开启线程 Thread t=new Thread(new ThreadStart(initUI));//执行更新Ui的方法 t.Start(); //也可以是这样 Thread t=new Thread(new ParameterizedThreadStart(/*方法*/)); t.Start(/*参数*/); }
上面使用的是Invoke,也可以使用BeginInvoke,前者是同步的,要等待工作线程完成,而后者是异步的。
3、使用BackgroundWorker
//实例化一个BackgroundWorker BackgroundWorker bgWorker=new BackgroundWorker(); bgWorker.DoWork += bgWorker_DoWork;//工作线程 bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;//主线程 //工作线程 void bgWorker_DoWork(object sender, DoWorkEventArgs e) { //后台耗时等 } void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //执行更新UI的操作 }
个人感觉BackgroundWorker跟Android里面的AsyncTask的工作原理应该是一样的。
4、SynchronizationContext
最开始自己使用最多的就是委托来实现线程通信,后面发现了这个SynchronizationContext。意思是 提供在各种同步模型中传播同步上下文的基本功能。private SynchronizationContext sync; public Form(){ ...... // 原意是获取当前线程的同步上下文 我的理解是获取当前线程的托管吧 sync= SynchronizationContext.Current; Thread t=new Thread(new ThreadStart(doInBackground)); t.Start(); } ...... //这是工作线程 private void doInBackground(){ ...... //后台工作完成后需要更新UI或者回到主线程 sync.Post(new SendOrPostCallback(InitUI),/*参数*/);//发送异步消息 //或者 sync.Send(new SendOrPostCallback(InitUI),/*参数*/);//发送同步消息 } private void InitUI(object obj){ //主线程操作 }
有没有觉得比委托更简单明了!
目前自己就遇到以上几种方法,也都使用过,后面遇到不同的方案也会补充。
相关文章推荐
- 浅谈一个线程通信代码的内存泄露及解决方案
- 《CLR Via C# 第3版》笔记之(十七) - 线程基础
- C#通过接口与线程通信(捕获线程状态)介绍
- C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别
- 串口通信中接收数据时延迟处理与缓存处理的解决方案(C#)
- C#通过接口与线程通信(捕获线程状态)示例代码
- Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息
- C#学习笔记之线程 - 通知Signal
- C#通过接口与线程通信(捕获线程状态)介绍
- C# 线程间互相通信
- JAVA学习笔记(1)_____模拟线程通信之生产者消费者问题
- 四种线程间的通信(笔记) - yuyunliuhen的专栏 - CSDNBlog
- c#学习笔记之串口通信【转】
- C#通过接口与线程通信(捕获线程状态)
- c#线程间的通信
- C# 串口通信 学习笔记
- 黑马程序员之c#学习笔记:描述线程与进程的区别?
- C# web通信解决方案
- iOS学习笔记-103.多线程02——线程状态、同步、通信
- C#学习笔记之线程 - 同步上下文