private static object EndSyncImpl(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } SynchronousAsyncResult syncResult = asyncResult as SynchronousAsyncResult; if (syncResult == null) { throw new ArgumentException("IAsyncResult object did not come from the corresponding async method on this type.", "asyncResult"); } // // IMPORTANT! The End method on SynchronousAsyncResult will // throw an exception if that's what Log did when // BeginLog called it. The unforunate side effect of this is // the stack trace information for the exception is lost and // reset to this point. There seems to be a basic failure in the // framework to accommodate for this case more generally. One // could handle this through a custom exception that wraps the // original exception, but this assumes that an invocation will // only throw an exception of that custom type. // return(syncResult.End()); }
// // The following two methods are helpers that provide boilerplate // implementations for implementing asnychronous BeginXXXX and // EndXXXX methods over a default synchronous implementation. // private static IAsyncResult BeginSyncImpl(AsyncCallback asyncCallback, object asyncState, Delegate syncImpl, params object[] args) { Debug.Assert(syncImpl != null); SynchronousAsyncResult asyncResult; var syncMethodName = syncImpl.Method.Name; try { asyncResult = SynchronousAsyncResult.OnSuccess(syncMethodName, asyncState, syncImpl.DynamicInvoke(args)); } catch (Exception e) { asyncResult = SynchronousAsyncResult.OnFailure(syncMethodName, asyncState, e); } if (asyncCallback != null) { asyncCallback(asyncResult); } return(asyncResult); }