多线程-委托的异步

委托同步方法

1、Invoke(...)

delegate string GetName(string name);

//实例化委托
GetName getname = new GetName(GetN);

var invokeName = getname.Invoke("1");
Console.WriteLine(invokeName);

2、直接  委托实例名字()

 getname("1");

委托异步调用
//异步回调方法,在异步执行完之后执行这个 方法。参数为IAsyncResult  异步执行的返回值  里面包含了异步执行
AsyncCallback acb = (t) =>
{
    Console.WriteLine(t.AsyncState);
    Console.WriteLine(t.IsCompleted);
    Console.WriteLine(t.CompletedSynchronously);
};
//BeginInvoke前面的参数,是委托的参数,     倒数第二个参数是回调方法 AsyncCallback参数IAsyncResult(注意:IAsyncResult会变成BeginInvoke的返回值),  最后一个参数会赋值给AsyncCallback的参数IAsyncResult里面的状态值
var stat = getname.BeginInvoke("1", acb, "状态值");
Console.WriteLine(stat.IsCompleted+"    "+stat.AsyncState);
//EndInvoke得参数为BeginInvoke的返回值。   EndInvoke会阻塞主线程    一直等到异步结束之后才主线程才往下走
var endValut = getname.EndInvoke(stat);
Console.WriteLine(endValut);
Console.ReadKey();
View Code

 

 主要就是

BeginInvoke(参数列表...(根据委托参数列表),回调参数(异步执行完之后执行的方法),状态值(会设置到BeginInvoke返回值里面的状态字段)),该方法返回IAsyncResult。

EndInvoke(BeginInvoke返回的类型IAsyncResult),该方法返回委托添加方法的真正返回值,该方法会阻塞主线程一直到异步执行完。

AsyncCallback

public delegate void AsyncCallback(IAsyncResult ar); 

定义:引用在相应异步操作完成时调用的方法。

参数:异步操作的结果。

可以看出他是一个委托,没有返回值,有一个参数。在异步执行完后才出发执行。

IAsyncResult

1、 public interface IAsyncResult

定义:表示异步操作的状态。

包含属性:

//
// 摘要:
//     表示异步操作的状态。
[ComVisible(true)]
public interface IAsyncResult
{
    //
    // 摘要:
    //     获取用户定义的对象,它限定或包含关于异步操作的信息。
    //
    // 返回结果:
    //     用户定义的对象,它限定或包含关于异步操作的信息。
    object AsyncState { get; }
    //
    // 摘要:
    //     获取用于等待异步操作完成的 System.Threading.WaitHandle。
    //
    // 返回结果:
    //     用于等待异步操作完成的 System.Threading.WaitHandle。
    WaitHandle AsyncWaitHandle { get; }
    //
    // 摘要:
    //     获取一个值,该值指示异步操作是否同步完成。
    //
    // 返回结果:
    //     如果异步操作同步完成,则为 true;否则为 false。
    bool CompletedSynchronously { get; }
    //
    // 摘要:
    //     获取一个值,该值指示异步操作是否已完成。
    //
    // 返回结果:
    //     如果操作完成则为 true,否则为 false。
    bool IsCompleted { get; }
}
View Code

 BeginInvoke返回的类型就是这个,还有AsyncCallback的参数也是这个,还有EndInvoke的参数也是这个。

2、IAsyncResult  的通用模式

    IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 FileStream 类提供了 BeginRead 和 EndRead 方法来从文件异步读取字节,它们是 Read 方法的异步版本

    Begin 方法包含同步方法签名中的任何参数,此外还包含另外两个参数:一个AsyncCallback 委托和一个用户定义的状态对象。委托用来调用回调方法,状态对象是用来向回调方法传递状态信息。该方法返回一个实现 IAsyncResult 接口的对象

    End 方法用于结束异步操作并返回结果,因此包含同步方法签名中的 ref 和 out 参数,返回值类型也与同步方法相同。该方法还包括一个 IAsyncResult 参数,用于获取异步操作是否完成的信息,当然在使用时就必须传入对应的 Begin 方法返回的对象实例

    开始异步操作后如果要阻止应用程序,可以直接调用 End 方法,这会阻止应用程序直到异步操作完成后再继续执行。也可以使用 IAsyncResult 的 AsyncWaitHandle 属性,调用其中的WaitOne等方法来阻塞线程。这两种方法的区别不大,只是前者必须一直等待而后者可以设置等待超时

    如果不阻止应用程序,则可以通过轮循 IAsyncResult 的 IsCompleted 状态来判断操作是否完成,或使用 AsyncCallback 委托来结束异步操作。AsyncCallback 委托包含一个 IAsyncResult 的签名,回调方法内部再调用 End 方法来获取操作执行结果

委托异步执行顺序

1、BeginInvoke(...)进入新的线程

2、线程执行完之后执行回调方法AsyncCallback()

3、如果有EndInvoke,主线程卡在EndInvoke那里,一直到新的线程执行完(并且回调方法AsyncCallback()也执行完)。

 

异步委托等待-WaitHandle

1、IAsyncResult.IsCompleted(异步委托BeginInvok返回的值。AsyncCallback的参数)

注意:这种等待不会关注回调函数,回调函数可能在他的前面或者后面执行

//线程等待
while (stat.IsCompleted)
{
    Thread.Sleep(20);
}
View Code

可以再等待的时候执行一些动作,但是可能会损耗事件。待优化。

2、IAsyncResult.AsyncWaitHandle

获取用于等待异步操作完成的 System.Threading.WaitHandle。(也就是返回该线程的等待句柄)

System.Threading.WaitHandle

定义:封装等待对共享资源的独占访问的操作系统特定的对象。

 

WaitOne()

定义:阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号。

可以设置等待的毫秒数,也可不设置

WaitHandle.WaitAll(WaitHandle[] waitHandles,...)

定义:等待指定数组中的所有元素都收到信号。(等待所有的waitHandle都执行完,就是所有的线程执行完)

这个是静态方法,第一个参数是表示要等待的waitHandles列表

WaitHandle.WaitAny(WaitHandle[] waitHandles,...)

定义:等待指定数组中的任一元素收到信号(也就是有一个执行完就可以了)

这个是静态方法,第一个参数是表示要等待的waitHandles列表

WaitHandle.SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn,....)

定义:向一个 System.Threading.WaitHandle 发出信号并等待另一个。(就是让一个线程等待另外一个线程)

这个是静态方法,第一个要发出信号的 System.Threading.WaitHandle。第二个参数是表示要等待的waitHandles列表。

 

注:没有委托就没有异步多线程。异步是多线程的基础。

本文例子下载

posted @ 2017-09-09 22:11  西伯利亚的狼  阅读(258)  评论(0编辑  收藏  举报