1

In a WinForms project I have an algorithm running that continually computes data and updates the UI. It looks like this:

async Task BackgroundWorkAsync() {
    while (true) {
        var result = await Compute();
        UpdateUI(result);
    }
}

Sometimes, depending on what result contains I want to show a MessageBox but continue running the algorithm immediately. The following does not work because it blocks further processing until the MessageBox is dismissed:

while (true) {
    var result = await Compute();
    UpdateUI(result);
    if (...) MessageBox.Show(...); //new code
}

How can I make the MessageBox.Show call non-blocking?

(Yes, this means that multiple message boxes might pop up at the same time. That's OK.)

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
boot4life
  • 4,966
  • 7
  • 25
  • 47

2 Answers2

2

As soon as the code is running at WinForms UI thread, you can use either Control.BeginInvoke if this code is inside a Form or Control, or the more general SynchronizationContext.Post like this

if (...)
    BeginInvoke(new Action(() => MessageBox.Show(...)));

or

if (...)
    SynchronizationContext.Current.Post(_ => MessageBox.Show(...), null);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
-1
while (true) {
    var result = await Compute();
    UpdateUI(result);
    if (...) Task.Run(() => { MessageBox.Show(...); });
}

That should suffice if you don't care about which button a user presses in the popup.

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Max Yakimets
  • 1,195
  • 7
  • 12
  • This runs the message box on a separate thread which makes it non-modal and causes multiple message loops. – boot4life Dec 20 '15 at 11:55
  • 1
    He-he, sorry for necroposting, it's been a while since I visited SO... Anyway: you wanted the message box to become non-blocking, wanted to receive multiple of them - you get it. Why then require now for them to be modal and reside within the main message loop? – Max Yakimets Apr 14 '21 at 07:50