当前位置: 主页 > 展览 >

Net线程间通信的异步机制 - cpcpc


信息来源:https://www.aysoal.com 时间:2017-10-07 22:03

线程间通信

  we的极度的格构成看下面的图片

图1

  we的极度的格构成看法线程间通信的规律:线程(Thread B(线)和飞行 通信), 原始的个人线程 必须做的事经过努力到达某事物使时间互相一致(使时间互相一致环境 环境), B线程使时间互相一致受话器联络线程环境的线程会谈,极度的应验都是在使时间互相一致环境中达到结尾的的.线程B有两种方式应验线程间的通信.

  原始的:受话器联络线程的使时间互相一致环境,阻挠出现线程,白色慈菇受话器联络实现,直到黄色慈菇送还(使时间互相一致环境中实现)领先的相干 (1->2->3->5)

  秒种: 受话器联络线程的使时间互相一致环境(实际上到处实现,1->2->3->5) ,白色的慈菇的应验,但没阻挠出现线程(原件线程,1->4->5),持续绿色慈菇。

  本文将经过以下类加以绍介

    ISynchronizeInvoke 鼻子

    SynchronizationContext 类

    AsyncOperation / AsyncOperationManager 类

  1. ISynchronizeInvoke 鼻子

  we的极度的格构成先看下面一节异步编码(窗口 有1个扣住/ 1)技术援助委构成把持),但当你点击扣住,实现异步受话器联络,达到结尾的后,注意到窗口 Form的 )技术援助委的主旨属性把持 Asynchronous End”.

Code

 1delegatevoid DoWork();
 2     privatevoid button1_Click(object sender, EventArgs e)
 3    {
 4       //附带方式,反省出现线程 5       Debug.WriteLine(string.Format("Window Form Method.Thread ID:#{0}",
 6Thread.CurrentThread.ManagedThreadId));
 7      //Label lblStatus 次要是把持线程[ 1 ] 8      this.lblStatus.Text = "Asynchronous 开端。";
 9      //运用付托的异步方式受话器联络10      DoWork work = DoWorkMethod;
11      work.BeginInvoke(OnWorkCallback, 任务)
12    }
13     void OnWorkCallback(IAsyncResult asyncResult)
14    {
15       //附带方式,反省出现线程16       Debug.WriteLine(string.Format("Asynchronous Callback Method.Thread ID:#{0}",
17Thread.CurrentThread.ManagedThreadId));
18       DoWork work =  as DoWork;
19       if (任务 != null)
20      {
21        work.EndInvoke(asyncResult);
22      }
23       // 认不出:线程间运转病号 不从lblstatus使被安排好把持线程会谈它24       this.lblStatus.Text = "Asynchronous End"; //是你这么说的嘛!评论[ 1 ]25    }
2627     void DoWorkMethod()
28    {
29       Thread.Sleep(3000);//耗费时间的的任务模仿30     }

运转编码,we的极度的格构成在秒十二排误审(异步方式体)。为什么?一个人P,在Windows窗体敷用切中要害使用,在表格属性的恶作剧者的无论哪个修正必须做的事达到结尾的。从安心线程的方式和属性不克不及变得安全会谈把持。从调试窗口,we的极度的格构成可以主教教区该扣住的应验(图 当单击事情,运转在ID线程 =#10; 在体内归纳的方式,运转在ID线程=#7.差额线程间不克不及直率的通信.

为了处置这一成绩,应验图 中 #10 和 #7 的通信,到isynchronizeinvoke 如此鼻子(鼻子从.NET Framework 1.0),3方式1属性

  BeginInvoke / EndInvoke 方式 : 异步方式

  Invoke 方式 : 使时间互相一致方式

  InvokeRequired 属性 : 看见源编码的实现线程

  让we的极度的格构成看法看详细的编码阐明(编码重写,内幕Label 而不是列表)

 1delegatevoid DoWork();
 2    privatevoid button1_Click(object sender, EventArgs e)
 3   {
 4      //校正州,添加到列表框 中 5      AddValue("Asynchronous 开端。");
 6      //运用付托的异步方式受话器联络 7      DoWork work = DoWorkMethod;
 8     work.BeginInvoke(OnWorkCallback, 任务)
 9   }
10     
11     void OnWorkCallback(IAsyncResult asyncResult)
12    {
13       DoWork work =  as DoWork;
14       if (任务 != null)
15      {
16        work.EndInvoke(asyncResult);
17      }
18       //方式:(1)呼叫把持受话器联络
19       //Action asyncUpdateState = UpdateStatus; //Action 绍介=> 附1
20       //Invoke(asyncUpdateState, 1:异步 完毕。)
2122       //方式:(2)直率的在异步受话器联络的线程23       UpdateStatus("2:异步 End.");
24    }
2526     void UpdateStatus(string 输入)
27    {
28       //你必要注意到把持 作业isynchronizeinvoke
29       //应验线程间的通信30       ISynchronizeInvoke async = this.listBoxStatus;
31       //(1)运用方式,InvokeRequired == false ,电流源(窗口 构成的主线程)32       if (async.InvokeRequired == false)
33        AddValue(输入);
34       else// (2)运用方式 == true ,安心线程的源(异步)35      { 
36         Action<string> action = new Action<string(州 =>
37        {
38          AddValue(status);
39        });
40         //受话器联络ISynchronizeInvoke 装备受话器联络 使时间互相一致方式,嵌线,直到受话器联络完毕
41         //你也可以运用isynchronizeinvoke BeginInvoke / EndInvoke方式装备应验异步受话器联络。42         async.Invoke(action, newobject[] { input });
43      }
44    }
45     
46     void AddValue(string 输入)
47    {
48       this.listBoxStatus.Items.Add(string.Format("[(#{2}){0}]Context is null:{1}", input,Thread.CurrentContext==null, Thread.CurrentThread.ManagedThreadId));
49   }
50    void DoWorkMethod()
51   {
52      Thread.Sleep(3000);//耗费时间的的任务模仿53    }

  在编码(updateStatus体),we的极度的格构成可以主教教区,在ISynchronizeInvoke async = 应验线程间的通信,MSDN的解说 应验此鼻子可以接纳注意到,事情赋予形体,并能回应问号事情 和窗 构成(主线) 在列表框 把持和异步方式(从另一个人线程)T的发展 InvokeRequired 决定飞行的发起,假设(1)运用方式,从窗口 Form 本性Control 受话器联络方式, InvokeRequired将送还false 发起而且线程(异步)假设运用(2)送还true.同时ISynchronizeInvoke 装备了异步(BeginInvoke+EndInvok)和使时间互相一致方式(Invoke)来应验线程间通信.Invoke 是下面的图1 原始的种显示 / BeginInvoke+EndInvok 有二

  1:在行为 / Func (T…, TResult) (复杂的说委员是使轻易的)知可以主教教区绍介

  Action:

  Func (T…, TResult):

  尽管如此应验线程间的通信, 图1阐明的审察,” 原始的个人线程 必须做的事经过努力到达某事物使时间互相一致(使时间互相一致环境 环境)”, 而在 没窗 构成(主线)应验环境赋予形体,假设没这每个的赋予形体是不使被安排好的。此后窗口 Form 做了些什么呢?

  we的极度的格构成看下面的编码(把持台顺序)

  Code

 1staticclass Program
 2  {
 3     staticvoid Main()
 4    {
 5       //1,在主 运转在主线程,反省ID和线程使时间互相一致环境 6       Console.WriteLine("{1},Synchronization Context is null?{0}",
 7         SynchronizationContext.Current == null, Thread.CurrentThread.ManagedThreadId);
 8 9     //2,在主 运转在主线程,加盖于化一个人空赋予形体结帐,反省ID和线程使时间互相一致环境10      Test a = new Test();
11      Console.WriteLine("{1},Synchronization Context is null?{0}",
12        SynchronizationContext.Current == null, Thread.CurrentThread.ManagedThreadId);
1314      //3,在主 运转在主线程,加盖于化一个人赋予形体(窗体恢宏)formtest,反省ID和线程使时间互相一致环境15       FormTest test = new FormTest();
16       Console.WriteLine("{1},Synchronization Context is null?{0}",
17         SynchronizationContext.Current == null, Thread.CurrentThread.ManagedThreadId);
1819       //4,在新线程中运转,反省ID和线程使时间互相一致环境20       new Thread(任务).Start();
2122      Console.Read();
23    }
24     staticvoid work()
25    {
26       Console.WriteLine("{1},Synchronization Context is null?{0}",
27         SynchronizationContext.Current == null, Thread.CurrentThread.ManagedThreadId);
28    }
29  }
30   publicclass FormTest :  { }
31   publicclass Test { }

  由编码和图可以看出(SynchronizationContext.Current == null 决定赋予形体设想在)使时间互相一致环境, formtest加盖于化的 当赋予形体(恢宏),默许的构成帮忙we的极度的格构成使被安排好一个人使时间互相一致环境赋予形体,对# 9主线 使时间互相一致环境赋予形体是做的,这执意为什么 没说辞的结算单使时间互相一致环境赋予形体,同时也注意到we的极度的格构成,翻开一个人新的线程# 10,线程自己没使时间互相一致环境。

  2. SynchronizationContext 类

  比拟isynchronizeinvoke 鼻子,SynchronizationContext (从.NET类 Framework 2)装备更多的方式来恶作剧使时间互相一致环境,应验线程间通信.在下面的包围中SynchronizationContext类空军将领由 Post/Send 应验方式。

  解码we的极度的格构成主教教区

  

1  publicvirtualvoid Post(SendOrPostCallback d, object 州)
2 {
3    ThreadPool.QueueUserWorkItem(new WaitCallback(), 州);
4 }
56  publicvirtualvoid Send(SendOrPostCallback d, object 州)
7 {
8   d(州);
9  }

Send = ISynchronizeInvoke 在受话器联络 图1使时间互相一致受话器联络是原始的。

  Post = ISynchronizeInvoke 切中要害BeginInvoke + 异步受话器联络EndInvoke。 图1二

  重写编码(或在WinForm 停飞设计图)

  

 1delegatevoid DoWork();
 2    privatevoid button1_Click(object sender, EventArgs e)
 3   {
 4      // 自动手枪使被安排好默许使时间互相一致环境赋予形体,
 5      //直率的会谈出现使时间互相一致环境 6      SynchronizationContext context = SynchronizationContext.Current;
 7      //校正州,添加到列表框 中 8      AddValue<string>("Asynchronous 开端。");
 9      //运用付托的异步方式受话器联络10       DoWork work = DoWorkMethod;
11      work.BeginInvoke(OnWorkCallback, 环境)
1213    }
14     void OnWorkCallback(IAsyncResult asyncResult)
15    {
16       AsyncResult async = (AsyncResult)asyncResult;
17       DoWork work = (DoWork)async.AsyncDelegate;
18      work.EndInvoke(asyncResult);
19       
20       //校正州21       UpdateStatus("Asynchronous End.", );
22    }
23     void UpdateStatus(object input,object sync环境)
24    {
25       //获取主线程(窗口) 在使时间互相一致环境赋予形体26       SynchronizationContext context = syncContext as SynchronizationContext;
27       //运用SynchronizationContext 异步考虑 方式28       SendOrPostCallback callback = new SendOrPostCallback(p => {
29         AddValue<object>(p);
30      });
31       context.Post(callback, 输入);//Post 异步,Send 使时间互相一致3233    }
34     void AddValue(T 输入)
35    {
36       this.listBoxStatus.Items.Add(string.Format("[(#{2}){0}]Context is null:{1}", input, Thread.CurrentContext == null, Thread.CurrentThread.ManagedThreadId));
37    }
38     void DoWorkMethod()
39    {
40       Thread.Sleep(3000);//耗费时间的的任务模仿41     }

  下面we的极度的格构成早已在主线程中说 自动手枪使被安排好默许使时间互相一致环境赋予形体, 在如此时分we的极度的格构成把使时间互相一致的语境下经过的电流参量,受话器后 方式的应验, Post 接纳方式 SendOrPostCallback 付托和额定的赋予形体 州参量,在Post方式体内受话器联络线程池的线程来应验().自然we的极度的格构成也可以直率的运用Send方式.

  下面we的极度的格构成看一下线程的编码(在把持台 停飞设计图)

  Code

 1staticclass Program
 2 {
 3    staticvoid Main()
 4   {
 5      Output("Main Thread 开端。");
 6      //使被安排好主线程使时间互相一致 Context 7      var context = new SynchronizationContext();
 8      //启动一个人新线程 9      Thread threadB = new Thread(任务)
10      threadB.Start(环境)
1112      Console.Read();
13    }
14     staticvoid work(object 环境)
15    {
16       Output("Thread B");
1718       //获取使时间互相一致环境赋予形体在主线程19       SynchronizationContext sc = context as SynchronizationContext;
2021       //主线程和异步通信,发送打招呼 陆地。22       sc.Post(new SendOrPostCallback(p =>
23      {
24        输入(P)
25       }), "Hello World");
26    }
27     staticvoid Output(object 值)
28    {
29       Console.WriteLine("[ThreadID:#{0}]{1}", Thread.CurrentThread.ManagedThreadId, 值);
30    }
31   }

  在主线程中由于没使时间互相一致环境,因而we的极度的格构成开端新的 SynchronizationContext(); 赋予形体,安心和 根本平稳的。从图中是一个人终止的解说图1秒,这标示后 是翻开一个人新的线程(咸成迟)运转。

  3. AsyncOperation / AsyncOperationManager 类

  AsyncOperation / AsyncOperationManager 类是SynchronizationContext 齐头并进一步封装典型, AsyncOperationManager在使被安排好AsyncOperation赋予形体的时分会流行出现线程的使时间互相一致环境赋予形体,保在AsyncOperation,因而we的极度的格构成会谈使时间互相一致环境更轻易。

  Code3.1

 1publicclass MySynchronizedClass
 2 {
 3    private AsyncOperation operation;
 4    publicevent EventHandler somethingHappened;
 5    public MySynchronizedClass()
 6   {
 7      //使被安排好AsyncOperation 赋予形体,使出现线程使时间互相一致环境的asyncoperation 8      operation = (null);
 910       Thread workerThread = new Thread(new ThreadStart(DoWork));
11      workerThread.Start();
12    }
1314     privatevoid DoWork()
15    {
16       SendOrPostCallback callback = new SendOrPostCallback(state =>
17       {
18          EventHandler handler = somethingHappened;
1920          if (处置顺序 != null)
21         {
22            handler(this, );
23         }
24       });
2526       operation.Post(callback, null);
27       //注意到128      operation.OperationCompleted();
29    }
30   }

编码很复杂,我不克不及解说,可以参照下面的极度的编码。 注意到1: AsyncOperation类中应验了OperationCompleted的方式. SynchronizationContext 此方式不实现。

  总结:

  程序同样线纸正是套装(除非异步), SynchronizationContext是最重要的,扩张的另类的,如SynchronizationContextSwitcher 安心更较年长者的主旨,详细介绍人下面的连结。 这是一个人正是重要的BackgroundWorker winform 类,有很多文字在附近的BackgroundWorker,如此不做解说。

上一篇:2015年圣诞节是什么时候 下一篇:没有了