首先这是我自己理解的结果,后面随着学习的深入发现问题的话我会再回来改。
串行和并行给我的感觉更多的是方法上的执行顺序
同步与异步给我更多的感觉是线程中的执行顺序,在这里我之前也遇到了一个误区,认为开了工作线程的话,那应该就是异步,然而这种理解是错误的。
在学校的时候,我们应该都接触过信号量机制SemaphoreSlim,这属于同步机制,我们在这里也开启了多个线程。
谈到线程,我也想说一下task,我们要清楚task和线程的区别,比起用线程池,用task是一种更好的选择,而且task也可以包装和简化同步异步的使用。
首先讲讲invoke和begininvoke,这里牵扯到了同步机制和异步机制,异步机制有一个begin/end模式,而我们的begininvoke和endinvoke也属于这种模式。
我们一般常用control(也就是主线程)和delegate(委托)来使用invoke和beginivoke。
在这里我先讲讲invoke、begininvoke之间的区别:
这是UI线程里的一段代码
public void HandleMessage(IBMessage message)
{
if (this.InvokeRequired)
{
MessageHandlerDelegate callback = new MessageHandlerDelegate(HandleMessage);
this.Invoke(callback, new object[] { message });
}
else
{
UpdateUI(message);
}
}
下面我们来理解这段代码: message我们不用管,只是一个参数,而UpdateUI(message);是UI线程里一个方法
this.InvokeRequired是用来判断调用handlemessage的这个线程是否为UI主线程或者说创建它线程,但是要注意的是,这里的结果恰好相反,如果是创建它的以外的线程,反而会为真,那么我们可以看到为真后执行了下面两句代码
MessageHandlerDelegate callback = new MessageHandlerDelegate(HandleMessage);
this.Invoke(callback, new object[] { message });
那么是什么意思呢?
这里就是我们control.invoke的使用了,这里的作用是阻塞当前创建它的以外的线程返回到创建它的线程执行下面的else方法,当然我们也可以理解这段代码为其他线程要想调用这个方法就必须回到主线程调用该方法,这个做法保证了控件的安全。
如果不好理解的话,我们可以这样理解
有人想找你借钱,他可以直接在你的钱包中拿,这样太不安全,因此必须让别人先要告诉你,你再从自己的钱包把钱拿出来借给别人,这样就安全了
而begininvoke的使用常常是伴随着endinvoke的,而使用begininvoke和endinvoke可以引申出
异步编程的三种模式
如果委托对象在调用列表中只有一个方法(也叫做引用方法),它就可以异步执行这个方法。
委托类的BeginInvoke方法和EndInvoke方法就是用来异步执行这个方法的。
- 当我们调用委托的BeginInvoke方法时,它开始在线程中的独立线程上执行引用方法,并且立即返回原始线程。原始线程可以继续,而引用方法会在线程池的线程中并行执行(原始线程和独立线程一起并行执行)
- 当程序希望获取已完成的异步方法的结果时,可以检查BeginInvoke返回的IAsyncResult的IsCompeleted属性,或调用委托的EndInvoke方法来等待委托完成。
异步编程的3种标准模式: