2

We have got a scenario where we show two forms in one WinForms app (.NET 4.0) next to each other. Changes in one form should trigger changes in the other form. Say contact A is loaded in one form, then the other form should show the contact details of the newly selected contact. These changes to the GUI can take a little bit as lots of data is loaded into grids for example.

Ideally I would like to update one form without blocking the other form at all.

I tried using a background worker and let the GUI-update-work happen in the dowork (via InvokeRequired) or alternatively the completed event, but to no avail: the work updating the GUI in one form seems to block any events in the other form - as I said - it's mostly GUI work that is taking up the time, not stuff like complex calculations that can be done in the background.

Is that to be expected that I can't update one form without the other being blocked? Is there any solution around it? (I have read a little bit about the async keyword of .net 4.5 - would that behave the same for example?)

Any ideas are welcome!

ManOnAMission
  • 1,023
  • 1
  • 12
  • 31
  • Unless you've done something to use two threads, you have *one* UI thread, so anything that happens on one thread blocks anyone from doing more on that thread until it's done doing what you've asked it to do. You could create the forms on different threads; but then you'll have to deal with marshaling back and forth to those threads (not necessarily free). – Peter Ritchie Feb 21 '14 at 20:02
  • If updating the grid from the data you collected in a worker thread already causes unacceptable delays then you are just doing it wrong. That would be similar to Google showing you all query matches on one web page. Very user unfriendly as well. Create usable UI and your program stops sucking mud automatically. – Hans Passant Feb 21 '14 at 20:15
  • @PeterRitchie Thanks, your comment abuot the single UI thread makes sense. – ManOnAMission Feb 21 '14 at 20:42
  • @HansPassant Fair enough, you have probably raised a good point here! – ManOnAMission Feb 21 '14 at 20:44
  • If you are loading so much data that it clogs your UI response, you may want to think about what you are doing and if there could be a better way of processing the data into smaller chunks. That said, in WinForms you can perform a `DoEvents()` to release processing of one form long enough to allow the other form to do some work. If you have massive amounts of data to load, I would add `DoEvents()` every X number of data elements processed. If you need more details, let me know. I'll get an example together for you. – Adam Zuckerman Feb 22 '14 at 02:23
  • @AdamZuckerman yes, a quick example would be great.. – ManOnAMission Feb 22 '14 at 06:08

2 Answers2

2

The quick example. You didn't specify a language, so C# it is.

private void someLongRunningProcess()
{
  // Set this to how many items you have to process
  // This could come from a List of objects, numbers of records, etc.
  int qtyremaining = 5000;

  do
  {
    // Process one item
    ...

    // Every hundredth item, release the thread
    if ((qtyremaining % 100) == 0)
    {
      System.Windows.Forms.Application.DoEvents();
    };

    // Decrement your stack size
    qtyremaining--;
  } while (qtyremaining > 0);
}

You may not need to update as quickly as every hundredth item. You might only need every 1,000 or 100,000. You can play with that until you get a good balance of screen responsiveness and items processed.

The full documentation on DoEvents().

Adam Zuckerman
  • 1,633
  • 1
  • 14
  • 20
1

Some background information you also might want to consider:

Why are most UI frameworks single threaded?

Why are most UI frameworks single threaded?

And as a good rule to follow: http://msdn.microsoft.com/en-us/library/ff649143.aspx#scag-ch06_topic4 "Using Tasks to Handle Interaction Between the UI Thread and Other Threads"

Community
  • 1
  • 1
DotNetDeveloper
  • 493
  • 1
  • 6
  • 16