-1

I found out that if construct a new task using the following way: var task = new Task(async action); task.Start();, the any call of any async method (await Task.Delay(), await new WebClient().DownloadStringAsync(), etc.) supposingly ignores await operator and immediately backs to the main thread.

If I run the same action using Task.Run(async action) way, then the same code works as expected.

Sample code:

class Program
{
    static async Task Main()
    {
        // way1 - it's working
        var goodTask = Task.Run(async () => await ProblemMethod("goodTask"));
        await goodTask;
        Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(goodTask)} is finished.");

        // way2 - it fails without any exceptions on line with GetRequestStreamAsync
        var poorTask = new Task(async () => await ProblemMethod("poorTask"));
        poorTask.Start();
        await poorTask;
        Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(poorTask)} is finished.");

        Console.ReadLine();
    }

    static async Task ProblemMethod(string taskName)
    {
        Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: It's a first line.");
        await Task.Delay(2000);
        Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: It's a last line.");
    }
}

Console output:

goodTask :: 18:52:50 :: It's a first line.
goodTask :: 18:52:52 :: It's a last line.
18:52:52 :: goodTask is finished.
poorTask :: 18:52:52 :: It's a first line.
18:52:52 :: poorTask is finished.
poorTask :: 18:52:54 :: It's a last line.

Why so strange behaviour? And, yeah, I know that the preferred and recommended way is to run tasks immediately, via Task.Run or Task.Factory.StartNew, but what should I do if I don't want to run my tasks immediately?

Googman
  • 131
  • 1
  • 1
  • 4
  • 1
    Note that `TaskFactory.StartNew()` is essentially the same as `new Task().Start()`. See marked duplicates for a few of the _many_ times your question has already been asked and answered on Stack Overflow. _"what should I do if I don't want to run my tasks immediately?"_ -- then don't run them. What possible reason could you have for creating a `Task` object that you don't intend to actually start immediately? Why is it a hardship to just wait to create that object until later, when you actually want it to start? – Peter Duniho Aug 11 '19 at 17:41

1 Answers1

-1

The answer is discussed here. Essentially the Task construction takes an Action<> and not a Func<> and so the async delegate is not really being treated as such.

Brad
  • 4,089
  • 2
  • 16
  • 26
  • While you're to be commended for making the effort to find the actual duplicate question, you should not post a new answer that is effectively a comment that simply refers to the actual duplicate question. – Peter Duniho Aug 11 '19 at 17:33
  • I also marked as a duplicate, but that does not help the user that asked the question until it gets enough close votes. As a result I figured providing the the link to the duplicate would be more immediately helpful. However I guess I could have done that as a comment so I'll do that in the future. – Brad Aug 12 '19 at 02:19