验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

C# SynchronizationContext、Send和Post怎么使用

阅读:1261 来源:乙速云 作者:代码code

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);
      }
    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>