Hi all,
I am migrating a Windows Form application from .Net 1.1 to 2.0. I try to
use BackgroundWorker object to handle a very lengthy process.
I have a separated class to handle some very complex logic. In .Net 1.1,
I create some events inside this class to notify WinForm the status of
process:
obj.OneFileStarted += new OneFileStartedEventHandler(obj_OneFileStarted);
obj.OneFileFinished += new OneFileFinishedEventHandler(obj_OneFileFinished);
obj.AllFinished += new AllFinishedEventHandler(obj_AllFinished);
obj.ErrorHappened += new ErrorHappenedEventHandler(obj_ErrorHappened);
......
System.Threading.Thread t = new System.Threading.Thread(new
System.Threading.ThreadStart(obj.LengthyJob));
t.Start();
Then in my WinForm class, I just hook these events to run the UI content
change based on status/progress of object processing method.
In new BackgroundWorker model, what is the proper way to notify UI of
different statuses/events? Because I only see a ReportProgress method which
can talk with outside world. I need more than this. If I don't make any
change, still use old way to receive events, I get "Cross-thread operation
not valid: Control 'labelFileName' accessed from a thread other than the
thread it was created on." exception, even though I change values of
Controls inside my event handler methods of WinForm.
private void obj_OneFileStarted(object sender, ProcessFileArgs e) {
// I have exception here: Cross-thread operation not valid: Control
'labelFileName' accessed from a thread other than the thread it was created
on.
labelFileName.Text = e.FileName;
}

Signature
WWW: http://www.imagestation.com/members/hardywang
ICQ: 3359839
yours Hardy
Nicholas Paldino [.NET/C# MVP] - 02 Oct 2006 20:18 GMT
Hardy,
It looks like you were being bad in .NET 1.1. In .NET 1.1, the Control
class didn't check to see if it's members were accessing it on the proper
thread. In .NET 2.0, they have changed this.
If you want to use the BackgroundWorker class, then in your operation,
when you call the ReportProgress event, you want to pass an object for the
userState parameter. This is what you will use to indicate what you should
do in the event handler that will process the event on the UI thread.
Hope this helps.

Signature
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
> Hi all,
> I am migrating a Windows Form application from .Net 1.1 to 2.0. I try
[quoted text clipped - 30 lines]
> labelFileName.Text = e.FileName;
> }
Hardy Wang - 03 Oct 2006 15:36 GMT
Thanks a lot!
> Hardy,
>
[quoted text clipped - 43 lines]
> > labelFileName.Text = e.FileName;
> > }
Jeffrey Tan[MSFT] - 03 Oct 2006 04:55 GMT
Hi Hardy,
Yes, just as Nicholas pointed out, this "Cross-thread operation not valid"
exception means you have performed an invalid operation in the winform
application.
Since winform controls are using STA threading model(this is a legacy win32
control threading issue), any worker(non-GUI) thread accessing to the GUI
control methods/properties must be marshaled with Control.Invoke method(see
this method in MSDN for more details) to keep thread-safe. This is .Net
winform multithreading programming rule and is prone to programming error.
.Net1.1 did not have build-in mechanism to detect this programming error,
however, .Net2.0 will popup a "Cross-thread operation not valid" exception
to notify this error.
To resolve this problem, we should marshal the calling to the GUI control
methods/properties with Control.Invoke method. Before doing this, we may
first use Control.InvokeRequired property to check if this marshaling is
required. Please refer to "Wrapping Control.Invoke" section in the article
below for more information:
http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/
Below is the normal steps to check if certain method is executed in a
non-GUI thread:
1. place a breakpoint in the Form_Load event, while this breakpoint is hit,
open "Debug->Windows->Threads" window to record the current thread(GUI
thread) id.
2. place a breakpoint in the method you want to check, while this
breakpoint is hit, open "Debug->Windows->Threads" window to compare the
current thread id with the previous recorded GUI thread id.
If they differ, it means your code is executing in a worker thread. The
marshaling is required.
Hope this helps.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Hardy Wang - 03 Oct 2006 15:36 GMT
Thanks for your information.
> Hi Hardy,
>
[quoted text clipped - 53 lines]
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no rights.