[英]TaskContinuationOptions.OnlyOnFaulted not considered flow control using exceptions?
I was under the impression that controlling flow with exceptions was considered a bad practice.我的印象是控制异常流被认为是一种不好的做法。
So then why would you do something like this:那么你为什么要做这样的事情:
var task = Task.Factory
.StartNew(() => command.Execute());
task.ContinueWith(t =>
{
// success callback
}, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t =>
{
Log.Error(string.Format("'{0}' failed.", command.GetType()), t.Exception);
// error callback
}, TaskContinuationOptions.OnlyOnFaulted);
When you could just as easily catch
the exception inside command.Execute()
, is there something i'm missing here?当您可以轻松地在
command.Execute()
中catch
异常时,我在这里缺少什么吗? Can tasks throw exceptions unrelated to the code they're executing?任务可以抛出与它们正在执行的代码无关的异常吗?
EDIT : How about if we're using c# 5's async
and await
keywords, would you say this would be better, or does catch all really not matter as in the above example?编辑:如果我们使用 c# 5 的
async
和await
关键字,你会说这会更好,还是像上面的例子一样,抓住一切真的无关紧要?
public class AsyncFooCommand : AsyncCommandBase<Bar>
{
public override Bar Execute()
{
try
{
var bar = // Do something that can throw SpecificException
Successful = true;
return bar;
}
catch (SpecificException ex)
{
// Log
}
}
}
public static class AsyncCommandExecutor<T>
{
// NOTE: don't care about sharing this between instances.
// ReSharper disable StaticFieldInGenericType
private static readonly ILog Log = LogManager.GetLogger(typeof(Infrastructure.Commands.AsyncCommandExecutor<>));
// ReSharper restore StaticFieldInGenericType
public static async Task<T> Execute(IAsyncCommand<T> command, Action<T> success = null, Action error = null)
{
var task = Task.Factory
.StartNew(() =>
{
return command.Execute();
});
task.ContinueWith(t => Log.Error(string.Format("'{0}' failed, something terrible happened.", command.GetType()), t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
T result = await task;
if (success != null && command.Successful)
{
success(result);
}
if (error != null && !command.Successful)
{
error();
}
return result;
}
}
You certainly could and there would be no need for the continuation.你当然可以而且没有必要继续下去。 It's simply a different approach.
这只是一种不同的方法。
However, if you catch the exception in the task and it runs to completion, to the outside world the task looks like it was successful instead of failing.但是,如果您在任务中捕获异常并且它运行完成,那么在外界看来,该任务看起来像是成功而不是失败。 If you have other continuations that are
TaskContinuationOptions.OnlyOnRanToCompletion
or other such options, and you technically failed to execute the command (and just caught the exception), that task will continue to run perhaps when it needed the antecedent to run successfully.如果您有其他延续,即
TaskContinuationOptions.OnlyOnRanToCompletion
或其他此类选项,并且您在技术上未能执行命令(并且刚刚捕获异常),则该任务可能会在需要先行项成功运行时继续运行。 It's more about task state management.更多的是关于任务 state 管理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.