委托同步方法
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();
主要就是
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; } }
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); }
可以再等待的时候执行一些动作,但是可能会损耗事件。待优化。
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列表。
注:没有委托就没有异步多线程。异步是多线程的基础。