捕获异步回调中抛出的exception

我有一个方法,它采用一个回调参数异步执行,但catch块似乎没有捕获同步调用抛出的任何exception( this.Submit引用同步方法)。

 public void Submit(FileInfo file, AnswerHandler callback) { SubmitFileDelegate submitDelegate = new SubmitFileDelegate(this.Submit); submitDelegate.BeginInvoke(file, (IAsyncResult ar) => { string result = submitDelegate.EndInvoke(ar); callback(result); }, null); } 

有没有办法捕获新线程抛出的exception并将其发送到原始线程? 另外,这是处理异步exception的“正确”方法吗? 我编写了我的代码,因此可以像这样调用(假设exception问题已修复):

 try { target.Submit(file, (response) => { // do stuff }); } catch (Exception ex) { // catch stuff } 

但有没有更合适或更优雅的方式来做到这一点?

这不是一个“最佳实践”解决方案,但我认为这应该是一个简单的解决方案。

而不是将委托定义为

 private delegate string SubmitFileDelegate(FileInfo file); 

将其定义为

 private delegate SubmitFileResult SubmitFileDelegate(FileInfo file); 

并按如下方式定义SubmitFileResult:

 public class SubmitFileResult { public string Result; public Exception Exception; } 

然后,实际进行文件提交的方法(未在问题中显示)应该像这样定义:

 private static SubmitFileResult Submit(FileInfo file) { try { var submissionResult = ComplexSubmitFileMethod(); return new SubmitFileResult { Result = submissionResult }; } catch (Exception ex) { return new SubmitFileResult {Exception = ex, Result = "ERROR"}; } } 

这样,您将检查结果对象,查看它是否设置了Result或Exception字段,并相应地执行操作。

如果您的目标是.NET 4.0,则可以使用新的任务并行库,并观察Task对象的Exception属性。

 public Task Submit(FileInfo file) { return Task.Factory.StartNew(() => DoSomething(file)); } private void DoSomething(FileInfo file) { throw new Exception(); } 

然后像这样使用它:

 Submit(myFileInfo).ContinueWith(task => { // Check task.Exception for any exceptions. // Do stuff with task.Result }); 

DoSomething是您想要异步调用的方法,而传递给ContinueWith的委托是您的回调。

有关TPL中exception处理的更多信息,请访问: http : //msdn.microsoft.com/en-us/library/dd997415.aspx

总之,没有。

当你调用submitDelegate.BeginInvoke ,它会生成新线程,返回并立即退出你的try / catch块(当新线程在后台运行时)。

但是,您可以捕获所有未处理的exception,如下所示:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(YourException);

这将捕获应用程序域中的所有内容(但不仅仅是您的异步​​方法)。