Keine Antwort für 4.0, aber erwähnenswert, dass Sie dies in .Net 4.5 noch einfacher machen können mit:
#pragma warning disable 4014
Task.Run(() =>
{
MyFireAndForgetMethod();
}).ConfigureAwait(false);
#pragma warning restore 4014
Das Pragma besteht darin, die Warnung zu deaktivieren, die besagt, dass Sie diese Aufgabe als Feuer ausführen und vergessen.
Wenn die Methode in geschweiften Klammern eine Aufgabe zurückgibt:
#pragma warning disable 4014
Task.Run(async () =>
{
await MyFireAndForgetMethod();
}).ConfigureAwait(false);
#pragma warning restore 4014
Lassen Sie uns das zusammenfassen:
Task.Run gibt eine Task zurück, die eine Compiler-Warnung (Warnung CS4014) generiert, die darauf hinweist, dass dieser Code im Hintergrund ausgeführt wird - genau das wollten Sie, daher deaktivieren wir die Warnung 4014.
Standardmäßig versuchen Aufgaben, "auf den ursprünglichen Thread zurückzugreifen". Dies bedeutet, dass diese Aufgabe im Hintergrund ausgeführt wird, und versuchen dann, zu dem Thread zurückzukehren, der sie gestartet hat. Oft feuern und vergessen Aufgaben werden beendet, nachdem der ursprüngliche Thread fertig ist. Dadurch wird eine ThreadAbortException ausgelöst. In den meisten Fällen ist dies harmlos - es sagt Ihnen nur, ich habe versucht, mich wieder anzuschließen, ich habe versagt, aber es ist Ihnen sowieso egal. Aber es ist immer noch etwas laut, ThreadAbortExceptions entweder in Ihren Protokollen in Production oder in Ihrem Debugger in local dev zu haben. .ConfigureAwait(false)
ist nur eine Möglichkeit, ordentlich zu bleiben und explizit zu sagen, dies im Hintergrund auszuführen, und das war's.
Da dies wortreich ist, insbesondere das hässliche Pragma, verwende ich dafür eine Bibliotheksmethode:
public static class TaskHelper
{
/// <summary>
/// Runs a TPL Task fire-and-forget style, the right way - in the
/// background, separate from the current thread, with no risk
/// of it trying to rejoin the current thread.
/// </summary>
public static void RunBg(Func<Task> fn)
{
Task.Run(fn).ConfigureAwait(false);
}
/// <summary>
/// Runs a task fire-and-forget style and notifies the TPL that this
/// will not need a Thread to resume on for a long time, or that there
/// are multiple gaps in thread use that may be long.
/// Use for example when talking to a slow webservice.
/// </summary>
public static void RunBgLong(Func<Task> fn)
{
Task.Factory.StartNew(fn, TaskCreationOptions.LongRunning)
.ConfigureAwait(false);
}
}
Verwendung:
TaskHelper.RunBg(async () =>
{
await doSomethingAsync();
}