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?
TaskFactory.StartNew()is essentially the same asnew 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 aTaskobject 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?