1

I want to have a method (Let's call it M1) execute some async code in a loop (Let's call that second method M2). On every iteration - the UI should be updated with the result of M2.

In order to await M2, M1 needs to be async. But M1 should run on the UI thread (to avoid race conditions) and therefore it will be called without an await.

Am I correct in thinking that in this way, M1's updating of the UI will be on the UI thread?


(Extra: It seems OK to have an async void in this case. Is this correct?)

ispiro
  • 26,556
  • 38
  • 136
  • 291
  • Yes, seems you are correct. Just try to do it. – Andrey Nasonov Oct 08 '15 at 22:27
  • Trying would be tricky because race conditions are usually unlikely in this case. I'm just being careful because someone _sometime_ will likely run into them. – ispiro Oct 08 '15 at 22:37
  • @ispiro btw, if you want to try `Task.Delay(10)` is likely the easiest way to create truly async method. – Alexei Levenkov Oct 08 '15 at 22:53
  • @AlexeiLevenkov Thanks for your time. I'm now looking into this whole thing. I really don't understand what's the point in async if it doesn't run on another thread. Anyway, I'm reading up on that now. Thanks again. – ispiro Oct 08 '15 at 22:57

1 Answers1

1

Yes. (assuming you use Synchronization Context that returns to UI thread - i.e. one from WinForm/WPF).

Note that it also means you can't schedule CPU-intensive operations that way as it will run on UI thread.

Using void async is quite standard method of handling events in WinForms:

void async click_RunManyAsync(...)
{
   await M1();
}

void async M1()
{
     foreach (...)
     {
        var result = await M2(); 
        uiElement.Text = result; 
     }
}

async Task<string> M2()
{
    // sync portion runs on UI thread
    // don't perform a lot of CPU-intensive work

    // off main thread, same synchronization context - so sync part will be on UI thread. 
    var result = await SomeReallyAsyncMethod(...); 

    // sync portion runs on UI thread
    // don't perform a lot of CPU-intensive work
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Thanks. But I'm not explicitly using any Synchronization Context and I'm using this in UWP - Windows Universal Apps. Is that still OK? – ispiro Oct 08 '15 at 22:34
  • Yes, the principle is the same – Andrey Nasonov Oct 08 '15 at 22:38
  • I don't understand your example - Since M1 is awaited - it will _not_ run on the UI thread. Isn't that so? – ispiro Oct 08 '15 at 22:38
  • @ispiro - It will use current context - if starting operation on UI thread than it will come back to UI thread, if one from thread pool - will continue on arbitrary thread. – Alexei Levenkov Oct 08 '15 at 22:39
  • But won't the `await` create a new thread for M1 so that `uiElement` will be updated from that second thread? – ispiro Oct 08 '15 at 22:40
  • @ispiro, the Synchronization Context is set by UI framework. It is guaranteed that M1 and M2 will both run on UI thread. – Andrey Nasonov Oct 08 '15 at 22:40
  • 1
    @ispiro `await` *does not* change what thread synchronous part of the code runs - so anything up to `await SomeReallyAsyncMethod` call will be on original thread. Synchronization context decides where execution continue after asynchronous operation ends. – Alexei Levenkov Oct 08 '15 at 22:41
  • 1
    @isipro, No, `await` will not create a new thread (using the Syncronization Context provided by UI) unless you order to create it manually using `await Task.Run(... cpu-bound code...)`. – Andrey Nasonov Oct 08 '15 at 22:41
  • OK. So it seems I misunderstood the whole `await` thing. So a) I _don't_ need to remove the `await` from M1. b) Any long calculations done in an `async` method _will_ stop the UI (unless using `Task.Run`). Did I understand correctly now? [I now see that I've been reading comments by two people. And they seem contradictory.] – ispiro Oct 08 '15 at 22:43
  • @ispiro sounds right (but I don't see Andrey's and my comments are contradicting each other - so there is likely something else :)) I'd recommend searching for something like "C# await new thread" on search engine of your choice to read more. I.e. http://stackoverflow.com/questions/13429294/how-different-is-await-async-from-threading, consider asking separate question if need more clarification as it would be better than long comment thread... – Alexei Levenkov Oct 08 '15 at 22:48