开发者

Invalid Cross thread Operations C#

I have a windows form with some controls on it. One of the controls is a textbox and the other one is listView. I also have a button (Upload) that uploads files based on the items selected item ListView object.

To report upload progress %, i added a progress bar that created a background worker thread that would upload the files, by contacting the server. The progress bar does not updates properly and appears unresponsive without the approach of creating background worker开发者_如何学Python.

Now, while uploading files, i need to get the selection from ListView and get files based on that selection. But when i try to access "ListView" from background worker thread I get an exception: System.InvalidOperationException: Cross-thread operation not valid:

What should i do to correct this exception?


In this case your processing thread wants to access your UI thread.

Example:

private delegate void UpdateTextDelegate(object value);

private void UpdateText(object value)
{
    if (this.textbox.InvokeRequired)
    {
        // This is a worker thread so delegate the task.
        this.textbox.Invoke(new UpdateTextDelegate(this.UpdateText), value);
    }
    else
    {
        // This is the UI thread so perform the task.
        this.textbox.Text = value.ToString();
    }
}


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 might see this exception when you debug applications that you wrote with the .NET Framework prior to .NET Framework version 2.0

BackgroundWorker also uses a thread to do it's job.

Look at this


No code should touch any Control unless it's running on the UI thread. This means invoking methods (other than Control.Invoke()) and setting/retrieving properties. The best way to accomplish this is to make liberal use of Control.InvokeRequired and Control.Invoke(). For your particular case, you may want to look into using a BackgroundWorker to do your file uploading.


You cannot access controls created on one thread from another thread. This is a good thing, trust me. The BackgroundWorker class exposes a couple of events that can help you accomplish what you want, namely ProgressChanged and RunWorkerCompleted.


I wrote a detailed guide to some of the techniques to handle this on a forum I frequent. Look at the explanation under the "Classic Marshalling" header for a walkthrough of what the implementation looks like.


Usually, I use the ReportProgress method of the BackgroundWorker component to marshall elements from the background thread to the UI thread.

You can simply pass the progress (integer) value and you can as well pass complex objects (non-GUI only, so no ListViewItems or the like) to the GUI thread in this event.


The good solution would be using Control.Invoke/Control.InvokeRequired - it helps executing code in the GUI thread (thus not throwing an exception).

The bad/ugly solution would be Control.CheckForIllegalCrossThreadCalls = false.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜