kev*_*314 9 c# lambda 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);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法捕获新线程抛出的异常并将其发送到原始线程?另外,这是处理异步异常的"正确"方法吗?我编写了我的代码,因此可以像这样调用(假设异常问题已修复):
try
{
target.Submit(file, (response) =>
{
// do stuff
});
}
catch (Exception ex)
{
// catch stuff
}
Run Code Online (Sandbox Code Playgroud)
但有没有更合适或更优雅的方式来做到这一点?
如果您的目标是.NET 4.0,则可以使用新的任务并行库,并观察Task对象的Exception属性.
public Task Submit(FileInfo file)
{
return Task.Factory.StartNew(() => DoSomething(file));
}
private void DoSomething(FileInfo file)
{
throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
Submit(myFileInfo).ContinueWith(task =>
{
// Check task.Exception for any exceptions.
// Do stuff with task.Result
});
Run Code Online (Sandbox Code Playgroud)
DoSomething你想要异步调用的方法在哪里,你传递给的委托ContinueWith就是你的回调.
有关TPL中异常处理的更多信息,请访问:http://msdn.microsoft.com/en-us/library/dd997415.aspx
这不是一个"最佳实践"解决方案,但我认为这应该是一个简单的解决方案.
而不是将委托定义为
private delegate string SubmitFileDelegate(FileInfo file);
Run Code Online (Sandbox Code Playgroud)
将其定义为
private delegate SubmitFileResult SubmitFileDelegate(FileInfo file);
Run Code Online (Sandbox Code Playgroud)
并按如下方式定义SubmitFileResult:
public class SubmitFileResult
{
public string Result;
public Exception Exception;
}
Run Code Online (Sandbox Code Playgroud)
然后,实际执行文件提交的方法(未在问题中显示)应该像这样定义:
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"};
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您将检查结果对象,查看它是否设置了Result或Exception字段,并相应地执行操作.
简而言之,不。
当您调用 时submitDelegate.BeginInvoke,它会生成新线程、返回并立即退出 try/catch 块(同时新线程在后台运行)。
但是,您可以捕获所有未处理的异常,如下所示:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(YourException);
然而,这将捕获应用程序域中的所有内容(不仅仅是您的异步方法)。
| 归档时间: |
|
| 查看次数: |
13932 次 |
| 最近记录: |