![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
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; } -- WWW: http://www.imagestation.com/members/hardywang ICQ: 3359839 yours Hardy |
#3
| |||
| |||
|
#4
| |||
| |||
|
|
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/is...ultithreading/ 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/subscripti...ult.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/subscripti...t/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
#5
| |||
| |||
|
|
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. -- - Nicholas Paldino [.NET/C# MVP] - mvp (AT) spam (DOT) guard.caspershouse.com "Hardy Wang" <hardywang (AT) newsgroups (DOT) nospam> wrote in message news:%236hC6Dl5GHA.756 (AT) TK2MSFTNGP05 (DOT) phx.gbl... 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; } -- WWW: http://www.imagestation.com/members/hardywang ICQ: 3359839 yours Hardy |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |