[英]Catching an exception thrown in an asynchronous callback
我有一个方法,它采用一个回调参数异步执行,但catch块似乎没有捕获同步调用抛出的任何异常( 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);
}
有没有办法捕获新线程抛出的异常并将其发送到原始线程? 另外,这是处理异步异常的“正确”方法吗? 我编写了我的代码,因此可以像这样调用(假设异常问题已修复):
try
{
target.Submit(file, (response) =>
{
// do stuff
});
}
catch (Exception ex)
{
// catch stuff
}
但有没有更合适或更优雅的方式来做到这一点?
如果您的目标是.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中异常处理的更多信息,请访问: http : //msdn.microsoft.com/en-us/library/dd997415.aspx
这不是一个“最佳实践”解决方案,但我认为这应该是一个简单的解决方案。
而不是将委托定义为
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字段,并相应地执行操作。
简而言之,没有。
当你调用submitDelegate.BeginInvoke
,它会生成新线程,返回并立即退出你的try / catch块(当新线程在后台运行时)。
但是,您可以捕获所有未处理的异常,如下所示:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(YourException);
这将捕获应用程序域中的所有内容(但不仅仅是您的异步方法)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.