C# 捕获异步回调中引发的异常
我有一个采用回调参数异步执行的方法,但是catch块似乎没有捕获同步调用引发的任何异常(C# 捕获异步回调中引发的异常,c#,asynchronous,lambda,callback,C#,Asynchronous,Lambda,Callback,我有一个采用回调参数异步执行的方法,但是catch块似乎没有捕获同步调用引发的任何异常(this.Submit指的是同步方法) 是否有方法捕获新线程抛出的异常并将其发送到原始线程?另外,这是处理异步异常的“正确”方法吗?我编写的代码可以这样调用(假设异常问题已修复): 但是,有没有更合适或更优雅的方法来做到这一点呢?简言之,没有 调用submitDelegate.BeginInvoke时,它生成新线程,返回并立即退出try/catch块(而新线程在后台运行) 但是,您可以捕获所有未处理的异常,如
this.Submit
指的是同步方法)
是否有方法捕获新线程抛出的异常并将其发送到原始线程?另外,这是处理异步异常的“正确”方法吗?我编写的代码可以这样调用(假设异常问题已修复):
但是,有没有更合适或更优雅的方法来做到这一点呢?简言之,没有
调用submitDelegate.BeginInvoke
时,它生成新线程,返回并立即退出try/catch块(而新线程在后台运行)
但是,您可以捕获所有未处理的异常,如下所示:
Submit(myFileInfo).ContinueWith(task =>
{
// Check task.Exception for any exceptions.
// Do stuff with task.Result
});
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"};
}
}
AppDomain.CurrentDomain.UnhandledException+=新的UnhandledExceptionEventHandler(YourException)代码>
但是,这将捕获应用程序域中的所有内容(不仅仅是异步方法)。如果您的目标是.NET 4.0,则可以利用新的任务并行库,并观察任务对象的异常
属性
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
});
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"};
}
}
其中,DoSomething
是您希望异步调用的方法,传递给ContinueWith
的委托是您的回调
关于TPL中异常处理的更多信息可以在这里找到:这不是一个“最佳实践”解决方案,但我认为它是一个简单的解决方案,应该可以工作
而不是将委托定义为
private delegate string SubmitFileDelegate(FileInfo file);
定义为
private delegate SubmitFileResult SubmitFileDelegate(FileInfo file);
并定义SubmitFileResult,如下所示:
public class SubmitFileResult
{
public string Result;
public Exception Exception;
}
然后,实际提交文件的方法(问题中未显示)应定义如下:
Submit(myFileInfo).ContinueWith(task =>
{
// Check task.Exception for any exceptions.
// Do stuff with task.Result
});
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"};
}
}
这样,您将检查结果对象,查看它是否设置了结果或异常字段,并相应地执行操作。第一个代码示例中的catch块将捕获回调或EndInvoke引发的异常。第二个代码示例中的catch块将捕获SubmitFileDelegate构造函数或BeginInvoke引发的任何异常。哪一个没有做你期望/希望它做的事?哎呀,忘记删除了。我希望第二个可以正常工作,但目前两者都不能正常工作。您能否说明SubmitFileDelegate
是如何定义的?它只是一个非常通用的私有委托字符串SubmitFileDelegate(FileInfo文件)代码>。那么,是否有处理异常的首选方法?我习惯于让回调类似于JS世界中的函数(err,result){},但我在我看过的C代码示例中没有看到类似的东西,所以我不确定在C中是否应该这样做:S@w0lf中国的答案基本上是,;您将响应类型中发生的异常包装起来,并在完成后将其拉出。但此调用不是同步的吗?我试着在BeginInvoke回调中放置一个try/catch(下面是您的示例),但它似乎没有捕获异常。不,它不是同步的。请注意,有两种Submit
方法:我上面描述的一种方法(必须与SubmitFileDelegate
定义相匹配)和您在问题中提出的另一种方法,BeginInvoke
是另一种方法(这意味着它是一个异步调用)。