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);
}
}
I have a couple issues with the leading answer to this question.
First, in a true 火与遗忘 situation, you probably won't await the task, so it is useless to append ConfigureAwait(false). If you do not await the value returned by ConfigureAwait, then it cannot possibly have any effect.
Second, you need to be aware of what happens when the task completes with an exception. Consider the simple solution that @ade-miller suggested: