1

Is there anyway to run a large number of UI updates without effecting the main thread in a C# winforms application?

I would like to avoid a long delay when a user clicks a specific event (which in my case is many close form calls to dispose of memory)

I know i can use BackgroundWorker to perform lengthy operations in the "do work" event, but the problem is that you cant change any UI in this event (it will cause a cross thread exception) - so i cant put my large number of close form calls here.

And I cant put the close form calls in the "worker completed" event because this is run on the main thread, and will eventually lockup the main thread causing a bad user experience.

I have thought about spawning a thread to handle closes only when the appication session is idle, but not sure if this is going to be a bit messy.

Marty
  • 2,965
  • 4
  • 30
  • 45
  • 1
    Why are the close form calls taking so much time? What are you doing that is time consuming. – paparazzo Oct 31 '12 at 13:22
  • Can you split out single heavy operation into multiple small and then dispatch to UI thread so UI thread? – sll Oct 31 '12 at 15:45

1 Answers1

2

You should use ProgressChanged event of BackgroundWorker to update UI. To enable this feature set WorkerReportsProgress property of your BackgroundWorker instance to true. Then you can update UI many times by sending data from DoWork event handler:

backgroundWorker.ReportProgress(percentage, yourCustomData);

It is recommended to Make Thread-Safe Calls to Windows Forms Controls. Here is the reason:

Access to Windows Forms controls is not inherently thread safe. If you have two or more threads manipulating the state of a control, it is possible to force the control into an inconsistent state. Other thread-related bugs are possible as well, including race conditions and deadlocks. It is important to ensure that access to your controls is done in a thread-safe way.

The .NET Framework helps you detect when you are accessing your controls in a manner that is not thread safe. When you are running your application in the debugger, and a thread other than the one which created a control attempts to call that control, the debugger raises an InvalidOperationException with the message, "Control control name accessed from a thread other than the thread it was created on."

This exception occurs reliably during debugging and, under some circumstances, at run time. You are strongly advised to fix this problem when you see it.

You can disable that exception:

Form.CheckForIllegalCrossThreadCalls = false;

But controls could (and sometime will) stop working.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • but is this also run on the main thread? from what i have read, progress changed and completed events are run on the main thread – Marty Oct 31 '12 at 12:25
  • Any update of UI will run on main thread (thread, in which controls where created) - winforms controls are not thread safe – Sergey Berezovskiy Oct 31 '12 at 12:28
  • thanks, i figured this was the case. so in my scenario i cant do much, the user will get a delay even when ProgressChanged is called? or will it be a delay they wont notice because the thread is only changed periodically? – Marty Oct 31 '12 at 12:32
  • If you allow for sleep in between the ProgressChanged events, the user will not notice... – Mr47 Oct 31 '12 at 12:41