溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#?SynchronizationContext、Send和Post怎么使用

發(fā)布時間:2023-05-04 15:38:38 來源:億速云 閱讀:89 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下C# SynchronizationContext、Send和Post怎么使用的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    C# SynchronizationContext及Send和Post使用

    1、(SynchronizationContext)同步上下文的作用

    SynchronizationContext其實就是實現(xiàn)線程之間通訊的。

    2、創(chuàng)建(SynchronizationContext)同步上下文的方法

    • 1)直接new創(chuàng)建一個SynchronizationContext同步上下文對象。

    • 2)winform程序通過SynchronizationContext.Current獲取UI線程的同步上下文對象。

    • 3)AsyncOperation和AsyncOperationManager類來操作同步上下文對象,不直接訪問同步上下文對象(SynchronizationContext),推薦這程方法。

    3、(SynchronizationContext)同步上下文的Send和Post方法

    看了一些解釋Send和Post方法,感覺弄得很復雜,我感覺其實簡單來說,

    • 1)Send方法就是同步調(diào)用,在當前線程上調(diào)用委托。

    • 2)Post方法就是異步調(diào)用,在線程池中的線程調(diào)用委托。

    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非常重要對象在構(gòu)造函數(shù)中。我們想要的
             //屬于線程的SynchronizationContext對象
             //這個對象正在被創(chuàng)建。
             //context= SynchronizationContext.Current;當前線程可能沒有SynchronizationContext對象;該線程尚未為設置SynchronizationContext對象。
             //如果是這樣,我們可以通過創(chuàng)建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學習筆記

    提供在各種同步模型中傳播同步上下文的基本功能。同步上下文的工作就是確保調(diào)用在正確的線程上執(zhí)行。

    同步上下文的基本操作

    Current 獲取當前同步上下文

    var context = SynchronizationContext.Current;

    Send 一個同步消息調(diào)度到一個同步上下文。

    SendOrPostCallback callback = o =>
                                     {
                                         //TODO:
                                     };
    context.Send(callback,null);
    • send調(diào)用后會阻塞直到調(diào)用完成。 

    • Post 將異步消息調(diào)度到一個同步上下文。

    SendOrPostCallback callback = o =>
                                    {
                                          //TODO:
                                    };
    context.Post(callback,null);

    和send的調(diào)用方法一樣,不過Post會啟動一個線程來調(diào)用,不會阻塞當前線程。

    使用同步上下文來更新UI內(nèi)容

    無論WinFroms和WPF都只能用UI線程來更新界面的內(nèi)容

    常用的調(diào)用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";
                           }));
    }

    使用同步上下文也可以實現(xiàn)相同的效果,WinFroms和WPF繼承了SynchronizationContext,使同步上下文能夠在UI線程或者Dispatcher線程上正確執(zhí)行

    System.Windows.Forms. WindowsFormsSynchronizationContext
    System.Windows.Threading. DispatcherSynchronizationContext

    調(diào)用方法如下:

    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); //調(diào)用
    }

    使用.net4.0的Task 可以簡化成

    private void button_Click(object sender, EventArgs e)
    {
                var  scheduler = TaskScheduler.FromCurrentSynchronizationContext(); // 創(chuàng)建一個SynchronizationContext 關(guān)聯(lián)的 TaskScheduler
                Task.Factory.StartNew(() => label1.Text = "Hello TaskScheduler", CancellationToken.None,
                                      TaskCreationOptions.None, scheduler);
    }

    以上就是“C# SynchronizationContext、Send和Post怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI