Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows窗体应用程序中的线程交叉_C#_Multithreading - Fatal编程技术网

C# Windows窗体应用程序中的线程交叉

C# Windows窗体应用程序中的线程交叉,c#,multithreading,C#,Multithreading,我在应用程序(WindowsForms)中使用了两个线程。一个线程用于获取客户端的缩略图图像,另一个线程用于获取客户端的全尺寸图像…其工作正常,但不正常。。。当我点击缩略图像按钮时,它正确地给出了缩略图像,然后我点击了全尺寸图像按钮,它也变成了全尺寸图像和缩略图像。。。然后返回到缩略图像按钮,它作为缩略图像和全尺寸图像也来了 两个线程交叉,这就是为什么我没有得到正确的输出 我怎样才能解决这个问题?告诉我这个问题的解决方法 这是我的密码 { System.Windows.Forms.Con

我在应用程序(WindowsForms)中使用了两个线程。一个线程用于获取客户端的缩略图图像,另一个线程用于获取客户端的全尺寸图像…其工作正常,但不正常。。。当我点击缩略图像按钮时,它正确地给出了缩略图像,然后我点击了全尺寸图像按钮,它也变成了全尺寸图像和缩略图像。。。然后返回到缩略图像按钮,它作为缩略图像和全尺寸图像也来了

两个线程交叉,这就是为什么我没有得到正确的输出

我怎样才能解决这个问题?告诉我这个问题的解决方法

这是我的密码

{
    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被永久地、不可恢复地锁定)

  • 可能需要某种类型的同步?我该如何解决这种同步?我对这个线程概念不太熟悉…我不明白。。。所以,你能在我的代码中给我一些解释或示例吗?苏瑞,你应该花几分钟阅读大家花时间提供的文档,然后自己动手做一下