// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime,
DateTime procDateTime);
// following inside of some client method
GetEnergyUsageDelegate nrgDel = GetEnergyUsage;
IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
while (!aR.IsCompleted) Thread.Sleep(500);
int usageCnt = nrgDel.EndInvoke(aR);
Charles 您的代码(上图)不正确。您无需旋转等待完成。 EndInvoke 将阻塞,直到 WaitHandle 发出信号。
如果你想阻塞直到完成,你只需要
nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));
或者
ar.AsyncWaitHandle.WaitOne();
但是如果你阻塞了,那么发出 anyc 调用有什么意义呢?您不妨只使用同步调用。更好的选择是不阻塞并传入 lambda 进行清理:
nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);
要记住的一件事是您必须调用 EndInvoke。很多人忘记了这一点并最终泄漏了 WaitHandle,因为大多数异步实现在 EndInvoke 中释放了等待句柄。