对于C#委托我们谈的比较多在此谈论的是C#委托中的同步调用和异步调用希望本文的实例能给大家平时的工作有所帮助
C#委托的Invoke方法用来进行同步调用同步调用也可以叫阻塞调用它将阻塞当前线程然后执行调用调用完毕后再继续向下进行
同步调用的例子
using System;
using SystemThreading;
public delegate int AddHandler(int a int b);
public class Foo
{
static void Main()
{
ConsoleWriteLine(**********SyncInvokeTest**************);
AddHandler handler = new AddHandler(Add);
int result = handlerInvoke();
ConsoleWriteLine(Do other work );
ConsoleWriteLine(result); ConsoleReadLine();
}
static int Add(int a int b)
{ ConsoleWriteLine(Computing +a+ + +b+ );
ThreadSleep();
ConsoleWriteLine(Computing Complete);
return a+b;
}
}
运行结果
**********SyncInvokeTest************** Computing + Computing Complete Do other work 同步调用会阻塞线程如果是要调用一项繁重的工作(如大量IO操作)可能会让程序停顿很长时间造成糟糕的用户体验这时候异步调用就很有必要了异步调用不阻塞线程而是把调用塞到线程池中程序主线程或UI线程可以继续执行委托的异步调用通过BeginInvoke和EndInvoke来实现
异步调用
using System;
using SystemThreading;
public delegate int AddHandler(int a int b);
public class Foo
{
static void Main()
{
ConsoleWriteLine(**********AsyncInvokeTest**************);
AddHandler handler = new AddHandler(Add);
IAsyncResult result = handlerBeginInvoke(nullnull);
ConsoleWriteLine(Do other work );
ConsoleWriteLine(handlerEndInvoke(result));
ConsoleReadLine();
}
static int Add(int a int b)
{
ConsoleWriteLine(Computing +a+ + +b+ );
ThreadSleep();
ConsoleWriteLine(Computing Complete);
return a+b;
}
}
运行结果
**********AsyncInvokeTest************** Do other work Computing + Computing Complete
可以看到主线程并没有等待而是直接向下运行了
但是问题依然存在当主线程运行到EndInvoke时如果这时调用没有结束(这种情况很可能出现)这时为了等待调用结果线程依旧会被阻塞
解决的办法是用回调函数当调用结束时会自动调用回调函数
回调异步
public class Foo
{
static void Main() {
ConsoleWriteLine(**********AsyncInvokeTest**************);
AddHandler handler = new AddHandler(Add);
IAsyncResult result = handlerBeginInvoke(new AsyncCallback(AddComplete)AsycState:OK);
ConsoleWriteLine(Do other work ); ConsoleReadLine();
}
static int Add(int a int b)
{
ConsoleWriteLine(Computing +a+ + +b+ );
ThreadSleep();
ConsoleWriteLine(Computing Complete);
return a+b;
}
static void AddComplete(IAsyncResult result)
{
AddHandler handler = (AddHandler)((AsyncResult)result)AsyncDelegate;
ConsoleWriteLine(handlerEndInvoke(result));
ConsoleWriteLine(resultAsyncState);
}
}