From what I've read, I thought Task.Run
was the same as Task.Factory.StartNew
. With Task.Run
just a newer and preferred way of doing things. However, I'm seeing a slight difference in behaviour with the following code.
I've created a simple .Net 6 console app.
Worker.cs has the content:
internal class Worker
{
private readonly HttpClient httpClient = new();
public async Task StartTaskRun(CancellationToken token)
{
await Task.Run(async () => await SomeWork(token));
}
public async Task StartTaskFactory(CancellationToken token)
{
await Task.Factory.StartNew(async () => await SomeWork(token));
}
private async Task SomeWork(CancellationToken token)
{
try
{
while (true)
{
var result = await httpClient.GetStringAsync("https://www.yahoo.com", token);
await Task.Delay(5000, token);
}
}
catch (TaskCanceledException)
{
Console.WriteLine("Task has been canceled");
}
}
}
And Program.cs has the content:
var cancellationTokenSource = new CancellationTokenSource();
var worker = new Worker();
//worker.StartTaskFactory(cancellationTokenSource.Token); // 1# Returns
//worker.StartTaskRun(cancellationTokenSource.Token); // 2# Returns
//await worker.StartTaskFactory(cancellationTokenSource.Token); // 3# Returns
//await worker.StartTaskRun(cancellationTokenSource.Token); // #4 Does not return
Console.WriteLine("Hello world");
Console.ReadLine();
cancellationTokenSource.Cancel();
Console.WriteLine("Cancelling");
Console.ReadLine();
In Program.cs, I have 4 different ways that I call the Start methods. The #1 and #2 calls work as intended. They make a fire and forget call to the async methods and the console shows the "Hello World" output and continues with the logic.
However, why does #3 and #4 differ in results? #3 continues execution in the same way as #1 and #2. However, #4 seems to continue to wait on the StartTaskRun() call?
Can anyone explain the difference in results on this please?