Trying to deal with asynchronous code execution. Took example from MSDN and simplified a little:

private async void button1_Click(object sender, EventArgs e) { int i = await emuAccessTheWebAsync(); label1.Text += i.ToString(); } async Task<int> emuAccessTheWebAsync() { Task<string> t = new Task<string>(() => { Thread.Sleep(3000); return "completed"; }); DoIndependentWork(); string urlContents = await t; return urlContents.Length; } 

After 3 seconds, as indicated inside the task, nothing happens. I tried to output the result inside the task, but when accessing label1 I get, of course, a cross-thread exception.

How to get the result out of the asynchronous method correctly? And is it possible to transfer some intermediate results to it from the main thread?

    2 answers 2

    You create a task manually, but do not launch it. Therefore, await t will never wait.

    It is correctly considered to create a “hot”, already running and running Task :

     Task<string> t = Task.Run(() => { Thread.Sleep(3000); return "completed"; }); 

    Another best option is not to perform the Task in a separate thread, and use non-blocking wait:

     Task<string> t = Task.Run(async () => { await Task.Delay(3000); return "completed"; }); 

    or for example

     async Task Temp() { await Task.Delay(3000); return "completed"; } async Task<int> emuAccessTheWebAsync() { Task<string> t = Temp(); DoIndependentWork(); string urlContents = await t; return urlContents.Length; } 
    • non-blocking wait? what is it and the better in one async to wrap it up again? - kvvk
    • @kvvk: Does not block the stream while waiting. In a large application, this can be important if threads are a consumable resource. Well, rather, you do not need to create a new thread. - VladD
    • and unless the very expression Task.Run (...) in essence does not create a separate thread? And how can it wait for something in parallel if not in a separate thread? - kvvk
    • one
      @kvvk: Task.Run performs on the thread pool. And to wait is very simple: you have an object in memory that is not executed, and is subscribed to some event. When the event arrives, it continues executing the code. - VladD

    Add

      static async Task<int> emuAccessTheWebAsync() { Task<string> t = new Task<string>(() => { Thread.Sleep(3000); return "completed"; }); //запуск t.Start(); string urlContents = await t; return urlContents.Length; }