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
  • 13,598
  • 5
  • 77
  • 79
boot4life
  • 4,636
  • 6
  • 22
  • 43

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
  • 179,274
  • 12
  • 254
  • 292
-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
  • 13,598
  • 5
  • 77
  • 79
Max Yakimets
  • 1,197
  • 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
  • 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