繁体   English   中英

我正在使用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();
}

异常消息:

跨线程操作无效:从创建该线程的线程以外的线程访问控件“ pictureBox1”。

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

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

使用BeginInvoke是个好方法吗? 还是我应该以其他方式解决它,如果可以,怎么办?

在Windows GUI编程中:

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

记住, BeginInvoke调用的代码实际上是在UI线程上运行的。 因此,如果将所有代码都放入BeginInvoke的DoWork中 ,则与不使用Backgroundworker相同-实际上,情况甚至更糟,因为创建新线程并编组对UI线程的调用会产生很大的性能开销。

因此,您仅应在必要时调用BeginInvoke当代码需要访问UI元素时,其余代码不应包装在BeginInvoke

暂无
暂无

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

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