首页 > 代码库 > 异步编程
异步编程
在c#中,同步方法可以通过声明具有相同参数的委托来实现异步编程,例如方法 void PrintString(string msg)可以通过声明一个委托delegate void PrintStringDel(string msg)并调用委托的BeginInvoke和EndInvoke方法来实现同步方法printString异步调用。
创建委托对象
PrintStringDel printStrDel=PrintString;
然后有四种方法来使用委托进行异步调用
1.BeginInvoke和EndInvoke方法
先调用BeginInvoke,然后做自己的工作,再调用EndInvoke方法等待方法完成。
var result = printStringDel.BeginInvoke("Hello world", null, null);
DoOtherWorkInMainThread();
printStringDel.EndInvoke(result);
2.使用IAsyncResult的AsyncWaitHandle的WaitOne方法等待异步完成之后再调用EndInvoke获得结果,与方法1相比,它的优点是WaitOne可以控制等待时间。
var result = printStringDel.BeginInvoke("Hello world", null, null);
DoOtherWorkInMainThread();
result.AsyncWaitHandle.WaitOne(-1, false);
printStringDel.EndInvoke(result);
3.轮询由 BeginInvoke 返回的 IAsyncResult,IAsyncResult.IsCompeted确定异步调用何时完成,然后调用 EndInvoke。
var result = printStringDel.BeginInvoke("Hello world", null, null);
DoOtherWorkInMainThread();
while (!result.IsCompleted)
{
Console.WriteLine("still wait!");
Thread.Sleep(1000);
}
printStringDel.EndInvoke(result);
4.将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。这是在强制装
换回调函数里面IAsyncResult.AsyncState(BeginInvoke方法的最后一个参数)成委托,然后用委托执行EndInvoke。
警告 始终在异步调用完成后调用 EndInvoke。
class Program
{
static void Main(string[] args)
{
PrintStringDel printStringDel = new Program().PrintString;
var result = printStringDel.BeginInvoke("Hello world", new AsyncCallback(CallBack), printStringDel);
DoOtherWorkInMainThread();
while (!result.IsCompleted)
{
Console.WriteLine("still wait!");
Thread.Sleep(1000);
}
Console.WriteLine("Completed!");
}
private static void DoOtherWorkInMainThread()
{
Console.WriteLine("do some other work.");
}
public delegate void PrintStringDel(string msg);
public void PrintString(string stringToPrint)
{
Thread.Sleep(1000 * 5);
Console.WriteLine(stringToPrint);
}
public static void CallBack(IAsyncResult ir)
{
(ir.AsyncState as PrintStringDel).EndInvoke(ir);
Console.WriteLine("callback is called");
}
}