C# 处理任务引发的异常
我有一个任务在WPF中运行了很长时间的操作:C# 处理任务引发的异常,c#,exception,exception-handling,task-parallel-library,C#,Exception,Exception Handling,Task Parallel Library,我有一个任务在WPF中运行了很长时间的操作: Task t = Task.Factory.StartNew(() => { try { process(cancelTokenSource.Token, CompressionMethod, OpInfo); } catch (OperationCanceledException) { logger.Info("Operation cancelled by the use
Task t = Task.Factory.StartNew(() =>
{
try
{
process(cancelTokenSource.Token, CompressionMethod, OpInfo);
}
catch (OperationCanceledException)
{
logger.Info("Operation cancelled by the user");
}
}, cancelTokenSource.Token);
try
{
t.Wait();
}
catch (AggregateException ae)
{
int i = 0;
}
private void process(CancellationToken token, CompressionLevel level, OperationInfo info)
{
// check hash
if (ComputeHash)
{
logger.Info("HASH CHECKING NOT IMPLEMENTED YET!");
MessageBox.Show(this,"HASH CHECKING NOT IMPLEMENTED YET!", "WARNING", MessageBoxButton.OK, MessageBoxImage.Warning);
}
token.ThrowIfCancellationRequested();
UserMsgPhase = "Operation finished";
return info;
}
问题是“MessageBox.Show”引发异常,但它未在“catch(AggregateException ae)”中捕获。我一直在读关于TPL异常处理的书,但我不明白为什么它没有被捕获。请帮我一下好吗?任务完成后,您可以检查其异常属性。您还有状态和IsCompleted属性,它们可能对您有用…检查。 如果您的任务已键入(返回结果),则访问myTask.result将引发此异常 此外,如果您正在运行.NET4.5,则可以使用async/await 例如:
public async void MyButton_OnClick(object sender, EventArgs e)
{
try
{
Task t = ...your task...;
var myResult = await t; // do whatever you like with your task's result (if any)
}catch
{
// whatever you need
}
}
正如您对同步代码所做的那样(但这不是一个实际的同步调用)我认为问题的
过程
方法是一个任务
,因此它看起来可以以不同的方式实现:
Task
,然后在任务父级中有一个任务子级TaskCreationOptions.AttachedToParent
选项AttachedToParent
将有助于向父任务捕获通知子任务异常:
故障子级的任何异常都将传播到父级
任务(除非父任务在它之前观察到这些异常
完成)
例子:
为了更简单,我省略了取消令牌部分
此外,您还可以添加私有故障处理程序,如:
//*Private failure handler*.
var failHandler = child.ContinueWith(t =>
{
//Oops, something went wrong...
}, TaskContinuationOptions.AttachedToParent|TaskContinuationOptions.OnlyOnFaulted);
正在引发什么类型的异常?您只捕获
操作取消异常
,因此如果不是这样,那么当然不会捕获它。您的第二个try catch和aggregateeexception
位于完全不同的块上,因此catch与您的process()
调用根本不相关。您应该发布一个更完整的代码示例。内部异常是{“调用线程无法访问此对象,因为其他线程拥有它。”}。但关键是我想通知调用线程(而不是发生异常的线程)操作失败。如果我没有捕获异常,那么AggregateException捕获不应该捕获它吗?只有当AggregateException捕获抛出AggregateException时,它才会被AggregateException捕获。不幸的是,我并不擅长多线程来帮助你。但基本上,除了你的UI线程之外,你还有其他的东西试图操纵UI(消息框),但它不能这样做,所以这就是为什么它会在你身上出错。此外,即使它抛出了正确的异常,因为try-catch没有嵌套在另一个try-catch中,它也不会捕获它。
//*Private failure handler*.
var failHandler = child.ContinueWith(t =>
{
//Oops, something went wrong...
}, TaskContinuationOptions.AttachedToParent|TaskContinuationOptions.OnlyOnFaulted);