我正在使用 backgroundworker 并得到:InvalidOperationException:跨线程操作无效 - 我应该如何处理它?

I'm using backgroundworker and getting: InvalidOperationException: Cross-thread operation not valid - how should I handle it?

考虑:

private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
    Bitmap newbmp = new Bitmap(512, 512);
    IEnumerable<Point> CommonList = null;
    StreamWriter w = new StreamWriter(@"c:\diff\diff.txt");
    pixelscoordinatesinrectangle = new List<Point>();
    pixelscoordinatesinrectangle = pointsAffected.ToList();
    DrawIt = false;
    for (int i = 0; i < trackBar1FileInfo.Length; i++)
    {
        DrawIt = true;
        this.BeginInvoke(new MethodInvoker(delegate
        {
            trackBar1.Value = i;

                    LoadPictureAt(trackBar1.Value, sender);
                    pictureBox1.Load(trackBar1FileInfo[i].FullName);

            ConvertedBmp = ConvertTo24(trackBar1FileInfo[trackBar1.Value].FullName);
            ConvertedBmp.Save(ConvertedBmpDir + "\ConvertedBmp.bmp");
            mymem = ToStream(ConvertedBmp, ImageFormat.Bmp);
        }));
        Button1Code();
        pictureBox1.Refresh();
        newpixelscoordinates = new List<Point>();
        newpixelscoordinates = pointsAffected.ToList();
        CommonList = pixelscoordinatesinrectangle.Intersect(newpixelscoordinates);
        foreach (Point s in CommonList)
        {
            w.WriteLine("The following points are the same" + s);
            newbmp.SetPixel(s.X, s.Y, Color.Red);
        }
    }
    w.Close();
    using (Graphics G = Graphics.FromImage(newbmp))
    {
        G.DrawRectangle(pen, rect);
    }
    newbmp.Save(@"c:\newbmp\newbmp.bmp", ImageFormat.Bmp);
    newbmp.Dispose();
}

异常消息:

Cross-thread operation not valid: Control 'pictureBox1' accessed from a thread other than the thread it was created on.

我尝试使用 this.BeginInvoke(new MethodInvoker(delegate

即使现在在使用 BeginInvoke 之后的代码时,它也会显示异常,所以我也需要在其他代码上使用 BeginInvoke。

使用 BeginInvoke 是个好方法吗?或者我应该用其他方式解决它,如果是的话如何?

在WindowsGUI编程中:

  1. 将耗时的任务移到单独的线程中以保持UI响应,您选择使用BackgroundWorker,这是一个不错的选择。
  2. 您无法从后台线程访问 UI 元素(Cross-thread operation not valid 异常),这就是为什么您需要调用 BeginInvoke 来访问图片框的原因。

请记住 BeginInvoke 调用的代码实际上是 运行 在 UI 线程上。所以如果你把 DoWork 中的所有代码都放在 BeginInvoke 中,这与不使用 Backgroundworker 是一样的——实际上更糟,因为创建一个新线程并编组调用 UI 线程有显着的性能开销。

所以你应该只在必要时调用 BeginInvoke - 当代码需要访问 UI 元素时,其余代码不应包含在 BeginInvoke.[=16 中=]