C#SynchronizationContext以及Send和Post使用解读
c#synchronizationcontext以及send和post使用解读
c# synchronizationcontext及send和post使用
1、(synchronizationcontext)同步上下文的作用
synchronizationcontext其实就是实现线程之间通讯的。
2、创建(synchronizationcontext)同步上下文的方法
- 1)直接new创建一个synchronizationcontext同步上下文对象。
- 2)winform程序通过synchronizationcontext.current获取ui线程的同步上下文对象。
- 3)asyncoperation和asyncoperationmanager类来操作同步上下文对象,不直接访问同步上下文对象(synchronizationcontext),推荐这程方法。
3、(synchronizationcontext)同步上下文的send和post方法
看了一些解释send和post方法,感觉弄得很复杂,我感觉其实简单来说,
- 1)send方法就是同步调用,在当前线程上调用委托。
- 2)post方法就是异步调用,在线程池中的线程调用委托。
4、示例代码
1)(synchronizationcontext)同步上下文使用示例代码
using system; using system.threading; namespace synchronizationcontextexample { public class mysynchronizedclass { private thread workerthread; private synchronizationcontext context; public event eventhandler somethinghappened; public mysynchronizedclass() { //获取当前synchronizationcontext非常重要对象在构造函数中。我们想要的 //属于线程的synchronizationcontext对象 //这个对象正在被创建。 //context= synchronizationcontext.current;当前线程可能没有synchronizationcontext对象;该线程尚未为设置synchronizationcontext对象。 //如果是这样,我们可以通过创建synchronizationcontext来简化 if(context == null) { context = new synchronizationcontext(); } workerthread = new thread(new threadstart(dowork)); workerthread.start(); } private void dowork() { context.post(new sendorpostcallback(delegate(object state) { eventhandler handler = somethinghappened; if(handler != null) { handler(this, eventargs.empty); } }), null); } } }
2)使用asyncoperation和asyncoperationmanager类示例代码
using system; using system.threading; using system.componentmodel; namespace synchronizationcontextexample { public class mysynchronizedclass { private thread workerthread; private asyncoperation operation; public event eventhandler somethinghappened; public mysynchronizedclass() { operation = asyncoperationmanager.createoperation(null); workerthread = new thread(new threadstart(dowork)); workerthread.start(); } private void dowork() { operation.post(new sendorpostcallback(delegate(object state) { eventhandler handler = somethinghappened; if(handler != null) { handler(this, eventargs.empty); } }), null); operation.operationcompleted(); } } }
c#同步上下文synchronizationcontext学习笔记
提供在各种同步模型中传播同步上下文的基本功能。同步上下文的工作就是确保调用在正确的线程上执行。
同步上下文的基本操作
current 获取当前同步上下文
var context = synchronizationcontext.current;
send 一个同步消息调度到一个同步上下文。
sendorpostcallback callback = o => { //todo: }; context.send(callback,null);
- send调用后会阻塞直到调用完成。
- post 将异步消息调度到一个同步上下文。
sendorpostcallback callback = o => { //todo: }; context.post(callback,null);
和send的调用方法一样,不过post会启动一个线程来调用,不会阻塞当前线程。
使用同步上下文来更新ui内容
无论winfroms和wpf都只能用ui线程来更新界面的内容
常用的调用ui更新方法是inovke(winfroms):
private void button_click(object sender, eventargs e) { threadpool.queueuserworkitem(backgroudrun); } private void backgroudrun2(object state) { this.invoke(new action(() => { label1.text = "hello invoke"; })); }
使用同步上下文也可以实现相同的效果,winfroms和wpf继承了synchronizationcontext,使同步上下文能够在ui线程或者dispatcher线程上正确执行
system.windows.forms. windowsformssynchronizationcontext system.windows.threading. dispatchersynchronizationcontext
调用方法如下:
private void button_click(object sender, eventargs e) { var context = synchronizationcontext.current; //获取同步上下文 debug.assert(context != null); threadpool.queueuserworkitem(backgroudrun, context); } private void backgroudrun(object state) { var context = state as synchronizationcontext; //传入的同步上下文 debug.assert(context != null); sendorpostcallback callback = o => { label1.text = "hello synchronizationcontext"; }; context.send(callback,null); //调用 }
使用.net4.0的task 可以简化成
private void button_click(object sender, eventargs e) { var scheduler = taskscheduler.fromcurrentsynchronizationcontext(); // 创建一个synchronizationcontext 关联的 taskscheduler task.factory.startnew(() => label1.text = "hello taskscheduler", cancellationtoken.none, taskcreationoptions.none, scheduler); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持硕编程。