// 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 twój kod (powyżej) jest niepoprawny. Nie musisz obracać się, czekając na zakończenie. EndInvoke będzie blokować do momentu zasygnalizowania WaitHandle.
Jeśli chcesz zablokować do czasu zakończenia, po prostu musisz
nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));
lub alternatywnie
ar.AsyncWaitHandle.WaitOne();
Ale jaki jest sens wydawania połączeń anyc, jeśli blokujesz? Równie dobrze możesz użyć połączenia synchronicznego. Lepszym rozwiązaniem byłoby nie blokowanie i przekazywanie lambda do czyszczenia:
nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);
Należy pamiętać, że musisz wywołać EndInvoke. Wiele osób zapomina o tym i w końcu wyciekają WaitHandle, ponieważ większość implementacji asynchronicznych zwalnia waithandle w EndInvoke.