I'm looking to run an async method as a long-running thread, as in using the TaskCreationOptions.LongRunning
option. In my testing I'm considering the thread as running as a "long-running" thread if it is not a thread-pool thread (i.e. I expect that Thread.CurrentThread.IsThreadPoolThread
will be false).
This is my attempt:
var task = Task.Factory.StartNew(DoWorkAsync,
CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
task.Unwrap().Wait();
static async Task DoWorkAsync()
{
Console.WriteLine("IsThreadPoolThread: " + Thread.CurrentThread.IsThreadPoolThread);
await Task.Delay(100);
Console.WriteLine("IsThreadPoolThread: " + Thread.CurrentThread.IsThreadPoolThread);
}
The output of this is:
IsThreadPoolThread: False
IsThreadPoolThread: True
meaning that after the first await
the thread is no longer like a long-running thread.
This outcome intuitively makes sense as I'm passing the TaskFactory.StartNew()
method a Func<Task>
where the generic type of Task
is simply interpreted as the result type of the Task
that is created by TaskFactory.StartNew()
, so I end up getting a Task<Task>
which completes once the async method returns its Task
, i.e. once the first await
statement is encountered.
Is there a way to have the entire execution of the async method run as a long-running thread, i.e. to have all continuations run as non-thread-pool threads?
Thanks for all the helpful comments on this question!
As @Theodor Zoulias pointed out, this is possible to do by using a custom TaskScheduler
.
However, the best answer to "how do you run an async method as a LongRunning task?" is probably "You don't". As @Charlieface pointed out the LongRunning
task option only makes sense for long-running blocking threads. The use of coroutines (achieved via the async/await construct) defeats the LongRunning
option because whenever an await
is encountered the relevant thread will be released and returned to the thread pool.