public IAsyncResult BeginInvoke(IService service, object[] args, AsyncCallback callback, object asyncState) { if (service == null) { throw new ArgumentNullException("service"); } SynchronousAsyncResult asyncResult; try { object result = Invoke(service, args); asyncResult = SynchronousAsyncResult.Success(asyncState, result); } catch (Exception e) { asyncResult = SynchronousAsyncResult.Failure(asyncState, e); } if (callback != null) { callback(asyncResult); } return(asyncResult); }
public object EndInvoke(IService service, IAsyncResult asyncResult) { if (service == null) { throw new ArgumentNullException("service"); } if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } SynchronousAsyncResult ar = asyncResult as SynchronousAsyncResult; if (ar == null) { throw new ArgumentException("IAsyncResult object did not come from the corresponding async method on this type.", "asyncResult"); } try { // // IMPORTANT! The End method on SynchronousAsyncResult will // throw an exception if that's what Invoke did when // BeginInvoke 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. We need to // think more about this. // return(ar.End("Invoke")); } catch (ArgumentException e) { throw TranslateException(e); } catch (TargetParameterCountException e) { throw TranslateException(e); } catch (TargetInvocationException e) { throw TranslateException(e); } }