奇妙的SynchronizationContext

     上一篇中已经讲了SynchronizationContext 的一些内容,现在让我们更加深入地去了解它!
     继上篇中的问题"在UI线程上对SynchronizationContext的使用,可以适用于其他线程呢?"
     OK,我们把它放置在非UI线程上,这是你用SynchronizationContext.Current的属性来获取,你会发现你得到的是null,这时候,你可能会说,既然它不存在,那么我自己创建一个SynchronizationContext对象,这样就没问题了吧!?可是,最后它并不会像UI线程中那样去工作。
    让我们看下面的例子:
复制代码
class  Program
{
    
private  static  SynchronizationContext mT1  =  null ;

    
static  void  Main( string [] args)
    {
        
//  log the thread id
         int  id  =  Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine(
" Main thread is  "  +  id);

        
//  create a sync context for this thread
        var context  =  new  SynchronizationContext();
        
//  set this context for this thread.
        SynchronizationContext.SetSynchronizationContext(context);

        
//  create a thread, and pass it the main sync context.
        Thread t1  =  new  Thread( new  ParameterizedThreadStart(Run1));
        t1.Start(SynchronizationContext.Current);
        Console.ReadLine();
    }

    
static  private  void  Run1( object  state)
    {
        
int  id  =  Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine(
" Run1 Thread ID:  "  +  id);

        
//  grab  the sync context that main has set
        var context  =  state  as  SynchronizationContext;

        
//  call the sync context of main, expecting
        
//  the following code to run on the main thread
        
//  but it will not.
        context.Send(DoWork,  null );

        
while  ( true )
            Thread.Sleep(
10000000 );
    }

    
static  void  DoWork( object  state)
    {
        
int  id  =  Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine(
" DoWork Thread ID: "  +  id);
    }
}
复制代码
输出的结果:
Main thread  is  10
Run1 Thread ID: 
11
DoWork Thread ID:
11
     注意上面的输出结果,DoWork和Run1是运行在同一线程中的,SynchronizationContext并没有把DoWork带入到主线程中执行,为什么呢?!
我们可以先看SynchronizationContext的原码( SynchronizationContext原代码):
Code
注意Send和Post的部分:
复制代码
public  virtual  void  Send(SendOrPostCallback d, Object state)
{
    d(state);
}

public  virtual  void  Post(SendOrPostCallback d, Object state)
{
    ThreadPool.QueueUserWorkItem(
new  WaitCallback(d), state);
}
复制代码
     Send就是简单在当前的线程上面去调用委托来实现,而Post是通过线程池来实现。
     这时候你也许会奇怪,为什么UI线程上,SynchronizationContext就发挥了不同的作用呢!其实在UI线程中使用的并不是SynchronizationContext这个类,而是WindowsFormsSynchronizationContext这个东东。

     它重写了Send和Post方法。至于它是如何重写实现的,这个我也不是很了解,也没有找到相关的文章,只是知道通过"消息泵"来实现的,但是细节就不清楚了,如果大家知道的话,可以告诉下我,我很想了解下!呵呵
     最后,我画了一副图,让我们更加清楚地了解SynchronizationContext在UI线程和一般线程之间的不同,
     

转载于:https://www.cnblogs.com/dabaotao/articles/7443815.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值