我正在使用 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编程中:
- 将耗时的任务移到单独的线程中以保持UI响应,您选择使用BackgroundWorker,这是一个不错的选择。
- 您无法从后台线程访问 UI 元素(
Cross-thread operation not valid
异常),这就是为什么您需要调用 BeginInvoke
来访问图片框的原因。
请记住 BeginInvoke
调用的代码实际上是 运行 在 UI 线程上。所以如果你把 DoWork 中的所有代码都放在 BeginInvoke 中,这与不使用 Backgroundworker
是一样的——实际上更糟,因为创建一个新线程并编组调用 UI 线程有显着的性能开销。
所以你应该只在必要时调用 BeginInvoke
- 当代码需要访问 UI 元素时,其余代码不应包含在 BeginInvoke
.[=16 中=]
考虑:
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编程中:
- 将耗时的任务移到单独的线程中以保持UI响应,您选择使用BackgroundWorker,这是一个不错的选择。
- 您无法从后台线程访问 UI 元素(
Cross-thread operation not valid
异常),这就是为什么您需要调用BeginInvoke
来访问图片框的原因。
请记住 BeginInvoke
调用的代码实际上是 运行 在 UI 线程上。所以如果你把 DoWork 中的所有代码都放在 BeginInvoke 中,这与不使用 Backgroundworker
是一样的——实际上更糟,因为创建一个新线程并编组调用 UI 线程有显着的性能开销。
所以你应该只在必要时调用 BeginInvoke
- 当代码需要访问 UI 元素时,其余代码不应包含在 BeginInvoke
.[=16 中=]