简体   繁体   English

使用BackgroundWorker进行线程安全的调用

[英]Making Thread-Safe Calls by using BackgroundWorker

i want to use BackgroundWorker for my code. 我想为我的代码使用BackgroundWorker。

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        if (worker.CancellationPending == true)
        {
            e.Cancel = true;

        }
        else
        {
            hladat();
        }

    }

and my function hladat() is 我的函数hladat()是

            int x = 0;


            while (x < 130)
            {

                for (trackBar7.Value = x; trackBar7.Value < 250-x; trackBar7.Value += 2)
                {
                    minR = trackBar7.Value;
                    System.Threading.Thread.Sleep(15);

                    if (((CV - CV / 4) < RV) && (RV < CV)&&(vyhovujedlzka()))
                    {
                        break;
                    }
                }

                trackBar7.Value = x;
                minR = x;

                for (trackBar8.Value = 250 - x; trackBar8.Value > x; trackBar8.Value -= 2)
                {
                    maxR = trackBar8.Value;
                    System.Threading.Thread.Sleep(15);

                    if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
                    {
                        break;
                    }
                }

                trackBar8.Value = 250-x;
                maxR = 250-x;

                for (trackBar9.Value = 0; trackBar9.Value < 254; trackBar9.Value += 2)
                {
                    minG = trackBar9.Value;
                    System.Threading.Thread.Sleep(15);

                    if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
                    {
                        break;
                    }

                }

                if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
                {
                    break;
                }
                x = x + 10;
                trackBar9.Value = 0;
                minG = 0;


        }

and when i start bgWorker it give me error for this part of code 当我启动bgWorker时,这部分代码给我错误

trackBar7.Value = x trackBar7.Value = x

"Cross-thread operation not valid: Control 'trackBar7' accessed from a thread other than the thread it was created on." “跨线程操作无效:控制'trackBar7'是从不是在其上创建线程的线程访问的。”

how can i repair this code???... thnx and sorry for my english =// 我该如何修复此代码???? ... thnx,对不起我的英语= //

Set WorkerReportsProgress() to True for your BackgroundWorker() control, then wire up the ProgressChanged() event. 将BackgroundWorker()控件的WorkerReportsProgress()设置为True,然后连接ProgressChanged()事件。

Now change: 现在更改:

trackBar7.Value = x;

To: 至:

backgroundWorker1.ReportProgress(x, trackBar7);

In the ProgressChanged() event, cast e.UserState back to TrackBar and set its Value() to e.Percentage : 在ProgressChanged()事件中,将e.UserState回TrackBar并将其Value()设置为e.Percentage

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        TrackBar tb = (TrackBar)e.UserState;
        tb.Value = e.ProgressPercentage;
    }

Alternate approach: 替代方法:

If you want to do it all from within hladat() itself, change: 如果要在hladat()本身中完成所有操作,请更改:

        trackBar7.Value = x;

To: 至:

        trackBar7.Invoke((MethodInvoker)delegate{
            trackBar7.Value = x;
        });

http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.85%29.aspx

Use this function to set the value: 使用此功能设置值:

delegate void SetValueCallback(TrackBar trackbar, int value);

private void SetValue(TrackBar trackbar, int value)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (trackbar.InvokeRequired)
    {   
         SetValueCallback d = new SetValueCallback(SetValue);
         this.Invoke(d, new object[] {trackbar, value });
    }
    else
    {
         trackbar.Value = value;
    }
 }

This should correct the set part. 这应该校正set零件。

As for the reading; 至于阅读; it's best to write the Value to a variable. 最好将Value写入变量。 In that case you won't need to access a UI-control for you logic, just read the variable. 在这种情况下,您无需为逻辑访问UI控件,只需读取变量即可。

Something like: 就像是:

for (int c = x; c < 250-x; c += 2)
{
    SetValue(trackBar7, c); 
    //etc.

You have a few options, either do the Invoke method Stefan mentioned , ReportProgress like Idle_Mind mentioned , or another option is to use IProgress<T> (if you are on .NET 4.0 you can get the classes and interfaces from the Microsoft.Bcl NuGet package). 您有几个选择,可以执行Infan Invoke方法Stefan ,执行Ipro_Ind这样的ReportProgress或执行IProgress<T> (如果您使用的是.NET 4.0,则可以从Microsoft获得类和接口)。包)。

The way it works is you create a Progress<T> object and set it up to do whatever update you need on the UI thread (it captures the SynchronizationContext of the thread it is currently running on when you create it, so create it on the UI thread), you then pass a IProgress<T> interface to the method you doing the updating and that method calls Report(T) 它的工作方式是创建一个Progress<T>对象,并将其设置为执行UI线程上所需的任何更新(它会在创建它时捕获当前正在运行的线程的SynchronizationContext ,因此请在UI线程),然后将IProgress<T>接口传递给进行更新的方法,然后该方法调用Report(T)

private Form1()
{
    //Snip

    trackBar7Progress = new Progress<int>(value => trackBar7.Value = value);
    trackBar8Progress = new Progress<int>(value => trackBar8.Value = value);
    trackBar9Progress = new Progress<int>(value => trackBar9.Value = value);
}

IProgress<int> trackBar7Progress;
IProgress<int> trackBar8Progress;
IProgress<int> trackBar9Progress;

then inside hladat() change your trackBar#.Value = x calls to trackBar#Progress.Report(x) 然后在hladat()内部更改您的trackBar#.Value = xtrackBar#Progress.Report(x)调用

//Snip

trackBar7Progress.Report(x);
minR = x;

for (trackBar8.Value = 250 - x; trackBar8.Value > x; trackBar8.Value -= 2)
{
    maxR = trackBar8.Value;
    System.Threading.Thread.Sleep(15);

    if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
    {
        break;
    }
}

trackBar8Progress.Report(250-x);
maxR = 250-x;

for (trackBar9.Value = 0; trackBar9.Value < 254; trackBar9.Value += 2)
{
    minG = trackBar9.Value;
    System.Threading.Thread.Sleep(15);

    if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
    {
        break;
    }

}

if (((CV - CV / 4) < RV) && (RV < CV) && (vyhovujedlzka()))
{
    break;
}
x = x + 10;
trackBar9Progress.Report(0);
minG = 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM