C# Windows窗体应用程序中的线程交叉
我在应用程序(WindowsForms)中使用了两个线程。一个线程用于获取客户端的缩略图图像,另一个线程用于获取客户端的全尺寸图像…其工作正常,但不正常。。。当我点击缩略图像按钮时,它正确地给出了缩略图像,然后我点击了全尺寸图像按钮,它也变成了全尺寸图像和缩略图像。。。然后返回到缩略图像按钮,它作为缩略图像和全尺寸图像也来了 两个线程交叉,这就是为什么我没有得到正确的输出 我怎样才能解决这个问题?告诉我这个问题的解决方法 这是我的密码C# Windows窗体应用程序中的线程交叉,c#,multithreading,C#,Multithreading,我在应用程序(WindowsForms)中使用了两个线程。一个线程用于获取客户端的缩略图图像,另一个线程用于获取客户端的全尺寸图像…其工作正常,但不正常。。。当我点击缩略图像按钮时,它正确地给出了缩略图像,然后我点击了全尺寸图像按钮,它也变成了全尺寸图像和缩略图像。。。然后返回到缩略图像按钮,它作为缩略图像和全尺寸图像也来了 两个线程交叉,这就是为什么我没有得到正确的输出 我怎样才能解决这个问题?告诉我这个问题的解决方法 这是我的密码 { System.Windows.Forms.Con
{
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
th = new Thread(new ThreadStart(startlooping));
th.Start();
}
void StartLooping()
{
localconnection();
for (int i = 0; i < Num_Picbox; i++)
{
clsImage pcimg = frmDisplay.Serviceobj.ConnectToPcAndGetImage(listBox1.Items[i].ToString(), imgid);
Image img = objConvertByteToStream.byteArrayToImage(pcimg.pcimage);
if (listBox1.Items[i].ToString() == pcimg.IPadd && imgid == 0)
{
shapes[i].Image = img;
}
pcimg = null;
}
}
private void PictureBox_Click(object sender, EventArgs e)
{
pb= sender as PictureBox;
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
thread = new Thread(new ThreadStart(GetImage));
thread.Start();
}
void GetImage()
{
pictureBox1.Visible = true;
btnBack.Visible = true;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
label1.Visible = true;
pictureBox1.Height = this.flowLayoutPanel1.Height;
pictureBox1.Width = this.flowLayoutPanel1.Width;
btnGetConnectedPcs.Location = new Point(168, 616);
btnGetImageFromSelectedPc.Location = new Point(352, 616);
for (; ; )
{
count++;
int imageid = 1;
localconnection();
string strIpaddress = listBox1.Items[Convert.ToInt32(pb.Name)].ToString();
.........................
.........................
}
}
{
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls=false;
th=新线程(新线程开始(令人吃惊));
th.Start();
}
虚空惊人
{
localconnection();
对于(int i=0;i
不要对正在使用的控件使用CheckForIllegalCrossThreads和Invoke。您可能需要快速查看一下。这可能会给你一些启示,给你一条通向成功的明确道路
祝你好运。我想你应该改用。永远不要使用
检查非法的CrossThreadCalls
;这是有原因的
它处理“编组”(获取一个线程上的调用以切换到另一个线程以进行UI更新)
这是一个很好的开端:
此外,您还需要在其他线程运行时控制UI。通常通过禁用按钮/菜单等来防止用户要求更多的东西,比如一个已经在运行了
至少应该使用控件。调用。当你的线程下载完图像后,它应该调用一个方法来显示它们。然后,该方法应检查this.invokererequired
,如果为真,则应通过this.Invoke
或this.BeginInvoke
调用自身。这将有效地切换回主UI线程,并避免您可能看到的错误
请把密码寄给我好吗?
好的,这一次你可以多吃一点,但你还需要掌握掌握掌握一些方向的技能,然后找到自己的路。如果我们帮助您解决这个问题的实际代码,您下次遇到问题时就会回来。我们更愿意让你像一个发条玩具一样前进,而不是像一辆遥控汽车一样全程驾驶:)
幕后工作者
我要把你介绍给警察局
BackgroundWorker是从工具箱中放到表单上的组件。它不像文本框那样是一个可视控件,而是更像一个计时器或工具提示
以最简单的形式使用它意味着订阅DoWork
和RunWorkerCompleted
事件,如MSDN文章中所述。当您希望进行某些下载时,需要执行以下操作:
- 禁用用户界面(以防止后续按钮按下)
- 设置某种进度/工作动画或消息
- 调用
BackgroundWorker.RunWorkerAsync
,传入一个对象,该对象包含告诉它该做什么的参数(即下载大小图像)
您案例中的DoWork
事件将被引发,并且您的方法将在与UI不同的线程中运行,因此不允许您在此方法中更新UI。编写下载图像的DoWork方法,并在下载完成后将DoWorkEventArgs.Result
属性设置为该图像集合
当DoWork
方法完成时,BackgroundWorker将触发RunWorkerCompleted
事件,并将调用您订阅的方法。此代码现在将自动再次在UI线程上运行,因此您应该执行以下操作:
- 报告
RunWorkerCompletedEventArgs.Error
属性中的任何错误(本质上这是DoWork方法中发生的任何未捕获错误。请在此处处理这些错误,以便您可以使用UI通知用户问题)
- 创建控件以显示RunWorkerCompletedEventArgs中包含的图像。
隐藏任何进度指标
重新启用您的UI(最好使用finally块,这样任何异常都不会导致您的UI被永久地、不可恢复地锁定)
可能需要某种类型的同步?我该如何解决这种同步?我对这个线程概念不太熟悉…我不明白。。。所以,你能在我的代码中给我一些解释或示例吗?苏瑞,你应该花几分钟阅读大家花时间提供的文档,然后自己动手做一下