私は、例外を伴う制御フローは悪い習慣と考えられていました。あなたは同じように簡単にcatch
command.Execute()
内部の例外が、私はここに欠けている何かがTaskContinuationOptions.OnlyOnFaultedは例外を使用してフロー制御と見なされませんか?
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);
がある可能性があり:
は、それではなぜこのような何かをしますか?タスクは実行中のコードと無関係に例外をスローできますか?
EDIT: いかが我々は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;
}
}
"タスクは、実行中のコードと無関係の例外をスローすることができますか?"はい - スレッドが別のスレッドによってアボートされた場合、タスクはThreadAbortExceptionをスローする可能性があります。これは、タスクに関連付けられたコードとは無関係です。 –
あなたのご意見に感謝します。 2番目の例の考えは? –
成功したコールバック、OnlyOnFaultedフラグ? – Henrik