我有一个在WPF中运行长时间操作的任务:
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异常处理的内容,但我不明白为什么它没有被捕获。拜托,你能帮助我吗?
答案 0 :(得分:2)
任务完成后,您可以检查其Exception属性。您还有Status和IsCompleted属性可能对您有用...
答案 1 :(得分:0)
检查Task.Exception。 如果您的任务是键入的(返回结果),那么访问myTask.Result将抛出此异常。
此外,如果您运行的是.Net 4.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
}
}
就像使用同步代码一样(但这不是实际的同步调用)
答案 2 :(得分:0)
我相信问题的process
方法是Task
,因此看起来可以用不同的方式实现:
您可以将流程实施为Task
,然后在任务父级中拥有一个任务子级。
然后您可以使用TaskCreationOptions.AttachedToParent
选项。
根据Stephen Toub,使用AttachedToParent
将有助于将子任务异常通知给父任务捕获:
有缺陷的子代的任何异常都会传播到父代 任务(除非父任务在其之前观察到这些异常) 完成)。
为了简化起见,我省略了取消令牌部分。
Task t = Task.Factory.StartNew(() =>
{
var process = new Task(() =>
{
//Copy here the process logic.
}, TaskCreationOptions.AttachedToParent);
//*Private failure handler*.
process.start();
});
try
{
t.Wait();
}
catch (AggregateException ae)
{
//handle exceptions from process.
}
此外,您可以添加一个私有失败处理程序,例如:
//*Private failure handler*.
var failHandler = child.ContinueWith(t =>
{
//Oops, something went wrong...
}, TaskContinuationOptions.AttachedToParent|TaskContinuationOptions.OnlyOnFaulted);