在我的项目中,我有主要形式。在那个Main表单上,我在运行时调用User Control。像这样运行的事件序列。
扫描条形码 - 对此代码执行某些操作
询问用户“您想要扫描更多吗?”然后显示“是/否”选项。这不是弹出窗口,我必须在我的触摸屏电脑上为Kiosk更新屏幕上的消息。
等待用户输入一段时间。
如果用户点击“是”,则接受其他条形码。
如果用户点击“否”,则进一步处理。
如果用户没有及时回复,请按照“否”回复进行进一步处理。
问题:
如何在线程之间显示可见按钮?
如果是用户回复,如何处理按钮点击事件。
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秒,如果用户输入然后继续按钮点击事件,如果没有,则继续这里。
我不确定Thread.sleep在这里是否合适。或者我必须使用ManualResetEvent和waitone?以及如何处理那里的按钮点击?
答案 0 :(得分:0)
如果你完全不知道你是否在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。 所以:
如果是15秒后需要隐藏按钮的UI线程,则必须像在上面的代码中那样在后台线程中运行它:
ThreadPool.QueueUserWorkItem(delegate { // Spawn a Background Thread
Thread.Sleep(15000);
ShowMoreVoucherOption(true);
});
如果它不是UI线程,那么这段代码就足够了:
Thread.Sleep(15000);
UpdateProgessLable("Your message.");
我猜你没有关于涉及UI的多线程的足够信息。要么了解更多信息,要么尝试这些解决方案,并希望你很幸运。
答案 1 :(得分:0)
Thread.Sleep,哈?看看你的规格(不是代码),我不会这样做。扫描条形码并启动计时器。每次用户及时点击“是”时重置计时器。如果用户错过了机会,请停止接受用户输入并处理已扫描的内容。您将需要一些表格关闭锁定以防止同时处理用户输入和计时器,并且您将摆脱不必要的Tread.Sleep。