Don't use Task.Run
, just make the event handler async
private async void TestButton_Click(object sender, RoutedEventArgs e)
{
await dedicated();
}
private async Task dedicated()
{
Console.WriteLine("running on task {0}", Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null");
await Task.Delay(TimeSpan.FromMilliseconds(100));
Console.WriteLine("running on task {0}", Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null");
}
Read more about Task.CurrentId
in Async Methods here:
So Task.CurrentId
returns null
because there is no task actually
executing.
Reply to comments
- "It still runs on the UI thread, and not a spawned task."
The case with a thread pool thread is included in the link. In particular look at this example
static void Main(string[] args)
{
var task = Task.Run(() => MainAsync());
task.Wait();
taskRun = task.Id.ToString();
Console.WriteLine(beforeYield + "," + afterYield + "," + taskRun);
Console.ReadKey();
}
static async Task MainAsync()
{
beforeYield = Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null";
await Task.Yield();
afterYield = Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null";
}
Again, the clarification is
the null
comes into play because the async
method is first executed as
an actual task on the thread pool. However, after its await
, it
resumes as a regular delegate on the thread pool (not an actual task).
- "my question is how to stop it from doing that"
This is an implementation detail of the async
call, I can only quote the link again:
It’s likely that this behavior is just the result of the easiest and
most efficient implementation.
So you can't and you should not stop it from doing that, as far as a truly async
call is concerned.
What you describe as the expected behavior instead is equivalent to a Task.Run
without await
private void expected()
{
Task task = Task.Run(() =>
{
Console.WriteLine("Before - running on task {0} {1}",
Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null",
Environment.CurrentManagedThreadId);
Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
Console.WriteLine("After - running on task {0} {1}",
Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null",
Environment.CurrentManagedThreadId);
});
}
Or a nested Task.Run
private void expected()
{
Task task = Task.Run(() =>
{
Console.WriteLine("Before - running on task {0} {1}",
Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null",
Environment.CurrentManagedThreadId);
var inner = Task.Run( async () =>
await Task.Delay(TimeSpan.FromMilliseconds(100)));
inner.Wait();
Console.WriteLine("After - running on task {0} {1}",
Task.CurrentId.HasValue ? Task.CurrentId.ToString() : "null",
Environment.CurrentManagedThreadId);
});
}
Output
Before - running on task 312 11
After - running on task 312 11
Before - running on task 360 11
After - running on task 360 11
Before - running on task 403 15
After - running on task 403 15