我有一个关于循环按钮点击事件的问题,我尝试了很多方法并搜索了许多页面以寻找过去一小时的简单答案,但事实是每个答案看起来都像外星人的代码,可能是因为我还在发展的新手.
这是我正在尝试做的简化版本:
private string Message = "Hello";
private void Spam(bool loop)
{
if (loop == true)
{
while (loop == true)
{
MessageBox.Show(Message);
}
}
else { MessageBox.Show("Spamming has stopped !! "); }
}
private void button1_Click(object sender, EventArgs e)
{
Spam(true);
}
private void button2_Click(object sender, EventArgs e)
{
Spam(false);
}
Run Code Online (Sandbox Code Playgroud)
显然这不是我的API,或者它是一个无用的东西发明,但是,代码本身很长并且你们总是要求"相关代码"(没有不尊重),所以就是这样.
我的问题:单击按钮2时打破垃圾邮件循环,我的代码看起来足够让API可以搞清楚,但每次点击按钮1时,API都会冻结.
ste*_*351 14
使用后台工作人员来完成您的工作.完成后,您可以使用取消功能打破它.您拥有它的循环将在同步执行时阻止UI线程,这就是您的GUI变得无法响应的原因.请注意,如果您与do work委托中的UI进行任何交互,则需要封送回UI线程(例如,通过调用).
private BackgroundWorker _worker = null;
private void goButton_Click(object sender, EventArgs e)
{
_worker = new BackgroundWorker();
_worker.WorkerSupportsCancellation = true;
_worker.DoWork += new DoWorkEventHandler((state, args) =>
{
do
{
if (_worker.CancellationPending)
break;
Console.WriteLine("Hello, world");
} while (true);
});
_worker.RunWorkerAsync();
goButton.Enabled = false;
stopButton.Enabled = true;
}
private void stopButton_Click(object sender, EventArgs e)
{
stopButton.Enabled = false;
goButton.Enabled = true;
_worker.CancelAsync();
}
Run Code Online (Sandbox Code Playgroud)
要记住一件重要的事情:
在执行代码时,用户无法与您的用户界面进行交互.
这意味着:您首先需要退出循环(即从Spam方法返回),然后用户可以单击Button2.
这是一个很难的事实,因为这意味着你无法以你想要的方式编写代码.幸运的是,有几种方法可以解决这个问题:
不要使用循环.使用某种计时器来做"垃圾邮件".Button1启动计时器,Button2停止计时器.什么样的计时器可用取决于您使用的用户界面库(WinForms有一个Timer,WPF有一个DispatcherTimer).
在后台线程中进行"垃圾邮件" .这将允许您的用户界面保持响应,并且您可以与后台线程进行通信,例如,通过设置a volatile Boolean.但是,这是一个高级主题(并且可能很快导致复杂的同步问题),因此我建议您先尝试其他选项.
| 归档时间: |
|
| 查看次数: |
15272 次 |
| 最近记录: |