Solve Cross Streaming Exception in WinForms

I am currently working with WinForms (in C #) and I need to run the application in the background. For this, I use asynchronous. When I launch the application, it shows an exception, for example

“Incorrect cross-flow operation: Control” is drawn from a stream other than the stream in which it was created.

How can I solve this error?

+8
multithreading c # winforms
source share
6 answers

When calling a method on a control, if the calling object is in a different thread than the one on which the control was created, you need to call it using Control. Call on . Here is a sample code:

// you can define a delegate with the signature you want public delegate void UpdateControlsDelegate(); public void SomeMethod() { //this method is executed by the background worker InvokeUpdateControls(); } public void InvokeUpdateControls() { if (this.InvokeRequired) { this.Invoke(new UpdateControlsDelegate(UpdateControls)); } else { UpdateControls(); } } private void UpdateControls() { // update your controls here } 

Hope this helps.

+9
source share

Most often, the best way to do this using WinForms is to use BackgroundWorker , which will start your work on a background thread, but provide you with a clean, clean way to report the status back to the user interface.

In many everyday .NET programs, explicitly creating threads or calling .Invoke is a sign that you are not completely using the framework (of course, there are many legitimate reasons to do low-level things too, it's just that they are less common than people sometimes understand).

+3
source share

You need to check if Invoke is required for the control you are trying to update. Something like that:

 Action<Control, string> setterCallback = (toSet, text) => toSet.Text = text; void SetControlText(Control toSet, string text) { if (this.InvokeRequired) { this.Invoke(setterCallback, toSet, text); } else { setterCallback(toSet, text); } } 
+2
source share

A sample that you might find useful is to check at the top of the functions that interact with the GUI to see if you are working in the correct thread or not, and activate the function if necessary. Like this:

  public delegate void InvocationDelegate(); public void DoGuiStuff(){ if (someControl.InvokeRequired){ someControl.Invoke(InvocationDelegate(DoGuiStuff)); return; } //GUI manipulation here } 

Using this template - if you are in the correct thread when the method is called, it does not call itself, but if you are in another thread, it will call itself and then return (therefore, the logic of manipulating the GUI only ever once).

+1
source share

Updated from Invoke to start Invoke

 // you can define a delegate with the signature you want public delegate void UpdateControlsDelegate(); public void SomeMethod() { //this method is executed by the background worker InvokeUpdateControls(); } public void InvokeUpdateControls() { if (this.InvokeRequired) { this.BeginInvoke(new UpdateControlsDelegate(UpdateControls)); } else { UpdateControls(); } } private void UpdateControls() { // update your controls here } 
0
source share

Changes in the user interface can be performed using the Control.Invoke () methods, this cross-thread exception can be resolved using the code snippet below.

 void UpdateWorker() { //Here ddUser is the user control //Action to be performed should be called within { } as like below code if (this.ddUser.InvokeRequired) ddUser.Invoke(new MethodInvoker(() => { ddUser.Size = new Size(100, 100); })); } 
0
source share

All Articles