线程间通讯:SynchronizationContext
SynchronizationContext的讲解,该博友已经是非常清楚了:
http://www.cnblogs.com/Kevin-moon/archive/2009/01/13/1374353.html
http://www.cnblogs.com/Kevin-moon/archive/2009/01/16/1376812.html
在此只是做个笔记:
一 故事背景
先做个比喻(不知道是否恰当):
线程A:国家A;
线程B:国家B;
SynchronizationContext对象A:国家A的内奸。
故事是这样的:
话说,国家A,有个方法叫引爆原子弹() ,调用这个方法就在它本国(线程A中)干些事情:引爆一个原子弹.
二 为什么需要SynchronizationContext这个内奸
有一天,国家B远程调用国家A.引爆原子弹().
可想而知, 国家A当然会说,干你xxYY,我顶你的肺,一边凉快去(抛出异常,非法操作)。
这时,国家B不甘心啦,找个内应:我们的主角--国家A的内奸(线程A中的SynchronizationContext对象)。
三 如何找到SynchronizationContext内奸
内奸不是说有就有的啦,上哪里去找呀:
如果线程A是
(1)UI线程,微软保证,该UI线程必有一个内置SynchronizationContext对象(国家A的必有内奸);这样把它找出来:
SynchronizationContext uiContext =SynchronizationContext.Current;
(2)非UI线程,该非UI线程就得自己创造出一个SynchronizationContex对象(国家A的没有内奸,得自己创造一个内奸)。这样把它创建出来:
1 // create a sync context for this thread 2 var context = new SynchronizationContext(); 3 // set this context for this thread. 4 SynchronizationContext.SetSynchronizationContext(context);
四 内奸SynchronizationContext的工作过程
1 线程A的某个地方 2 { 3 //用以上方法得到SynchronizationContext对象(内奸) 4 SynchronizationContext context = ...; 5 6 // 创建线程B 7 Thread threadB = new Thread(线程B中的方法); 8 9 //线程A将内奸传递给线程B 10 threadB.Start(context); 11 } 12 13 14 private void 线程B中的方法(object state) 15 { 16 SynchronizationContext context = state as SynchronizationContext; 17 18 for (int i = 0; i < 1000; i++) //要引爆1000次!!!!,我顶你个肺啊 19 { 20 //线程之间在开始通讯。即:内奸开始引爆 21 //内奸有两种方式引爆:Send(同步)和Post(异步) 22 context.Send(引爆原子弹, null);//同步就是:爆炸了再逃跑
23 context.Post(引爆原子弹, null);//异步就是:边引爆边逃跑,两不误 24 } 25 } 26 27 private void 引爆原子弹(object state) 28 { 29 //在国家A(在线程A)中引爆原子弹(更新界面等); 30 }
五 原子弹在何处引爆
话说内奸SynchronizationContext引爆了原子弹,但是这颗原子弹爆炸地点据环境选择爆炸地点,(我顶你个肺)。
那方法:
1 private void 引爆原子弹(object state) 2 3 { 4 //在国家A(在线程A)中引爆原子弹(更新界面等); 5 }
到底将在哪个线程中执行(在那个国家爆炸)。
根据个人测试有如下情况:
如果线程A(国家A)是:
(1)UI线程。不管内奸SynchronizationContext是用Send方法还是Post方法,方法 void 引爆原子弹(object state) 都在线程A中执行(国家A中爆炸)。
(2)非UI线程,就看内奸SynchronizationContext是用Send方法还是Post方法而定了。
【1】内奸SynchronizationContext是用Send方法,方法 void 引爆原子弹(object state) 都在线程B中执行(国家B中爆炸,国家B玩火自焚啊,国家A的内奸SynchronizationContext良心发现了)。
【2】内奸SynchronizationContext是用Post方法,方法 void 引爆原子弹(object state) 都在一个新的线程C中执行(国家C中爆炸,国家C郁闷了没招谁惹啊)。
六 撒u啦啦