Mit System.Threading.Tasks.Task<TResult>
muss ich die Ausnahmen verwalten, die ausgelöst werden könnten. Ich suche nach dem besten Weg, das zu tun. Bisher habe ich eine Basisklasse erstellt, die alle nicht erfassten Ausnahmen innerhalb des Aufrufs von verwaltet.ContinueWith(...)
Ich frage mich, ob es einen besseren Weg gibt, das zu tun. Oder auch wenn es ein guter Weg ist, das zu tun.
public class BaseClass
{
protected void ExecuteIfTaskIsNotFaulted<T>(Task<T> e, Action action)
{
if (!e.IsFaulted) { action(); }
else
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
/* I display a window explaining the error in the GUI
* and I log the error.
*/
this.Handle.Error(e.Exception);
}));
}
}
}
public class ChildClass : BaseClass
{
public void DoItInAThread()
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew<StateObject>(() => this.Action())
.ContinueWith(e => this.ContinuedAction(e), context);
}
private void ContinuedAction(Task<StateObject> e)
{
this.ExecuteIfTaskIsNotFaulted(e, () =>
{
/* The action to execute
* I do stuff with e.Result
*/
});
}
}
quelle
t
ist die Ausnahme.SynchronizationContext
, falls erforderlich.Sie können eine benutzerdefinierte Task-Factory erstellen, in der Aufgaben mit eingebetteter Ausnahmebehandlungsverarbeitung erstellt werden. Etwas wie das:
using System; using System.Threading.Tasks; class FaFTaskFactory { public static Task StartNew(Action action) { return Task.Factory.StartNew(action).ContinueWith( c => { AggregateException exception = c.Exception; // Your Exception Handling Code }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously ).ContinueWith( c => { // Your task accomplishing Code }, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously ); } public static Task StartNew(Action action, Action<Task> exception_handler, Action<Task> completion_handler) { return Task.Factory.StartNew(action).ContinueWith( exception_handler, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously ).ContinueWith( completion_handler, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously ); } };
Sie können die Verarbeitung von Ausnahmen für Aufgaben, die in dieser Factory erstellt wurden, in Ihrem Client-Code vergessen. Gleichzeitig können Sie noch warten, bis solche Aufgaben erledigt sind, oder sie im Fire-and-Forget-Stil verwenden:
var task1 = FaFTaskFactory.StartNew( () => { throw new NullReferenceException(); } ); var task2 = FaFTaskFactory.StartNew( () => { throw new NullReferenceException(); }, c => { Console.WriteLine("Exception!"); }, c => { Console.WriteLine("Success!" ); } ); task1.Wait(); // You can omit this task2.Wait(); // You can omit this
Aber wenn Sie ehrlich sind, bin ich mir nicht sicher, warum Sie einen Code für die Vervollständigung haben möchten. In jedem Fall hängt diese Entscheidung von der Logik Ihrer Anwendung ab.
quelle