C# SynchronizationContext以及Send和Post使用解读

作者:你の猫 时间:2023-10-16 04:27:28 

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);
}

来源:https://blog.csdn.net/qq_41231360/article/details/90208042

标签:C#,SynchronizationContext,Send,Post
0
投稿

猜你喜欢

  • android多种滑动冲突的解决方案

    2021-11-16 11:20:10
  • Android在JNI中使用ByteBuffer的方法

    2021-11-08 21:14:35
  • IntelliJ IDEA 安装教程2019.09.23(最新版)

    2023-08-24 23:01:44
  • C#通过xpath查找xml指定元素的方法

    2023-06-22 11:55:29
  • Java基础之堆内存溢出的解决

    2023-11-10 20:06:30
  • Flutter开发setState能否在build中直接调用详解

    2022-05-17 14:55:27
  • IDEA2022创建Maven Web项目教程(图文)

    2022-09-25 02:30:44
  • 一文读懂Spring Bean的生命周期

    2022-11-01 04:01:20
  • IDEA:Git stash 暂存分支修改的实现代码

    2023-11-29 09:16:35
  • SpringBoot 如何编写配置文件

    2023-07-14 10:38:24
  • Android实现控制摄像头拍照

    2022-06-03 02:14:06
  • 代理模式:JAVA静态代理和动态代理的实例和实现详解

    2023-06-05 02:19:27
  • C#多线程的相关操作讲解

    2022-01-13 18:32:12
  • java中LinkedList使用迭代器优化移除批量元素原理

    2021-12-05 11:26:07
  • java虚拟机原理:Class字节码二进制文件分析

    2022-02-06 09:02:33
  • C#在DataTable中根据条件删除某一行的实现方法

    2022-03-09 05:34:19
  • Android10.0实现本地音乐播放(附源码下载)

    2022-12-05 20:29:40
  • C#如何优雅的结束线程

    2022-07-27 19:45:27
  • Android自定义view Path 的高级用法之搜索按钮动画

    2023-12-23 06:53:28
  • Android开发中编写蓝牙相关功能的核心代码讲解

    2021-07-26 00:24:53
  • asp之家 软件编程 m.aspxhome.com