Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
618 views
in Technique[技术] by (71.8m points)

c# - BackgroundWorker - Cross-thread operation not valid

I have a winform application (one form), on this form there is a RichTextBox. In the constructor of this form I create an instance of the class MyClass. In the “Form_Load” I call the method Initialisation from MyClass instance.

In the form constructor

myClass = new MyClass(RichTextBox richTextBox);

In the Form_Load

myClass.Initialisation();

In the Initialisation method, in a loop, I read some parmeters do other stuffs. To not freeze the application (because some operation can take a while, some seconds), I use a BackgroundWorker. I use it like this (see code below).

When I execute, I get this error : Cross-thread operation not valid: Control ‘richTextBox’ accessed from a thread other than the thread it was created on.

Could you tell me how solve this ? Work perfect when I don't access the richTextBox

public Class MyClass
{
    static BackgroundWorker _bw;
    public MyClass()
    {
        _bw = new BackgroundWorker
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };
        _bw.DoWork += bw_DoWork;
        _bw.ProgressChanged += bw_ProgressChanged;
        _bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    }
    static void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        foreach (....)
        {
            if (....)
            {
                richtextBox.Text.AppendText("MyText");
            }
        }
        e.Result = true;
    }
    static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){}
    static void bw_ProgressChanged(object sender, ProgressChangedEventArgs e){}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Using BackgroundWorker doesn't exempt you of the normal threading rules - such as that only the UI thread can access UI components.

If you want to update the UI from a BackgroundWorker other than using the progress/completion events (which are raised on the UI thread) you need to use Control.Invoke / Control.BeginInvoke just as you would in other situations. For example:

if (....)
{
    Action action = () => richtextBox.Text.Add("MyText");
    richtextBox.Invoke(action); // Or use BeginInvoke
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...