C# 用户控件上的多线程-按钮单击事件

C# 用户控件上的多线程-按钮单击事件,c#,.net,multithreading,C#,.net,Multithreading,在我的项目中,我有主窗体。在主窗体上,我在运行时调用用户控件。事件的顺序是这样运行的 扫描条形码-对此代码执行一些处理 询问用户“是否要扫描更多内容?”然后显示“是/否”选项。这不是弹出窗口,我必须更新我的触摸屏电脑屏幕上的信息 等待用户输入一段时间 如果用户单击“是”,则接受其他条形码 如果用户单击“否”,则进行进一步处理 如果用户没有及时回复,则按照“否”回复进行进一步处理 问题: 如何在线程之间显示按钮 用户回复时如何处理按钮点击事件 void ShowMoreVoucherOption(

在我的项目中,我有主窗体。在主窗体上,我在运行时调用用户控件。事件的顺序是这样运行的

  • 扫描条形码-对此代码执行一些处理

  • 询问用户“是否要扫描更多内容?”然后显示“是/否”选项。这不是弹出窗口,我必须更新我的触摸屏电脑屏幕上的信息

  • 等待用户输入一段时间

  • 如果用户单击“是”,则接受其他条形码

  • 如果用户单击“否”,则进行进一步处理

  • 如果用户没有及时回复,则按照“否”回复进行进一步处理

  • 问题:

  • 如何在线程之间显示按钮

  • 用户回复时如何处理按钮点击事件

    void ShowMoreVoucherOption(bool showhide)
    {
        if (this.btnYes.InvokeRequired)
        {
            this.BeginInvoke((MethodInvoker)(() => btnYes.Visible = showhide));
            this.BeginInvoke((MethodInvoker)(() => btnNo.Visible = showhide));
        }
        else
        {
            btnYes.Visible = true;
            btnNo.Visible = true;
        }
        Application.DoEvents();
    }
    
  • 我在下面的线程之间调用这个例程。这不是UI线程

    UpdateProgessLabel("Would you like to add more vouchers?");
    ShowMoreVoucherOption(true);
    Thread.Sleep(15000);
    Dofuthrerporcessing(); // in case user does not give input
    
    现在,等待15秒,若用户输入,则在按钮单击事件上继续,若否,则在此处继续


    我不确定。睡在这里合适还是不合适。还是必须使用ManualResetEvent和waitone?如果你完全不知道你是否在UI线程中(这似乎是这个问题的重点),那么你应该创建一个后台线程来为你做这项工作。最简单的方法是执行以下操作:

    if(SomeKindOfAFormOrAControl.InvokeRequired) // You are not in the UI Thread
    {
      Thread.Sleep(15000);
      UpdateProgessLable("Your message.");
    }
    else // You are in the UI Thread
    {
      ThreadPool.QueueUserWorkItem(delegate {  // Spawn a Background Thread
        Thread.Sleep(15000);
        UpdateProgessLable("Your message.");
      });      
    }
    //Your UI thread will keep running from this point if
    //SomeKindOfAFormOrAControl.InvokeRequired was false.
    
    这就是你要找的吗

    编辑:

    在UI线程中,您不必调用Invoke,您可以从那里操作UI;事实上,当您不在UI线程中时,必须调用Invoke。 因此:

    如果是UI线程需要在15秒后隐藏按钮,则必须在后台线程中运行它,就像我在上面代码中所做的那样:

    ThreadPool.QueueUserWorkItem(delegate {  // Spawn a Background Thread
        Thread.Sleep(15000);
        ShowMoreVoucherOption(true);
      }); 
    
    如果它不是UI线程,那么这段代码就足够了:

    Thread.Sleep(15000);
    UpdateProgessLable("Your message.");
    

    我猜您没有足够的关于涉及UI的多线程的信息。要么了解更多,要么尝试这些解决方案,希望你好运。

    Thread.Sleep,哈?看看你的规格(不是代码),我不会这么做。扫描条形码并启动计时器。每次用户及时单击“是”时重置计时器。若用户错过了机会,停止接受用户输入并处理已经扫描的内容。您将需要一些表单关闭锁定,以防止同时处理用户输入和计时器,并且您将摆脱不必要的踏板。睡眠。

    完全脱离主题,但它是标签,而不是标签。MNGwinn-不确定什么脱离主题,是的,谢谢更正。我已编辑了您的标题。请看“”,其中的共识是“不,他们不应该”。目前我在UI线程中,这就是为什么我调用这个。Invoke((MethodInvoker)(()=>lblProgress.Text=strMessage));这运行得很好,就像我必须显示/隐藏按钮一样。并且必须及时捕获这些按钮的点击事件。这是我的错误,我不在UI线程中,这就是为什么我必须调用进程来刷新标签以在UI上显示消息。这很好用。我对按钮的可见性有问题。我以同样的方式调用ShowMoreVoucherOption,但它正在停止我的UI。