我的印象是,控制流量与异常被认为是一种不好的做法。
那么为什么你会这样做: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);
当您catch
内的异常command.Execute()
变得容易时,我在这里缺少什么?任务可以抛出与它们正在执行的代码无关的异常吗?
修改:
如果我们使用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;
}
}
答案 0 :(得分:6)
你当然可以而且不需要延续。这只是一种不同的方法。
但是,如果你在任务中捕获异常并且它运行完成,那么对于外界来说,任务看起来是成功的而不是失败的。如果您有TaskContinuationOptions.OnlyOnRanToCompletion
的其他延续或其他此类选项,并且您在技术上无法执行该命令(并且只是捕获了异常),则该任务将在需要前提条件成功运行时继续运行。它更多地是关于任务状态管理。