我有一个关于按钮单击事件循环的问题,在过去的一个小时中,我尝试了许多方法并搜索了许多页面以寻找简单的答案,但事实是每个答案看起来都像是外来代码,可能是因为我仍然对开发来说非常新。
这是我正在尝试做的简化版本:
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);
}
显然,这不是我的API,或者发明起来毫无用处,但是代码本身很长,你们总是要求“相关代码”(不要轻视),所以就可以了。
我的问题:单击按钮2突破垃圾邮件循环,对我来说,代码看起来不错,API可以确定,但是每次单击按钮1时,API都会冻结。
使用后台工作者来完成您的工作。完成后,您可以使用取消功能来取消它。循环执行时,循环将阻塞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();
}
更新2019:BackgroundWorker
现在已基本过时,已由async/await
易于使用的更高版本的C#中的功能取代。这是如何使用该功能实现相同功能的示例:
private CancellationTokenSource _canceller;
private async void goButton_Click(object sender, EventArgs e)
{
goButton.Enabled = false;
stopButton.Enabled = true;
_canceller = new CancellationTokenSource();
await Task.Run(() =>
{
do
{
Console.WriteLine("Hello, world");
if (_canceller.Token.IsCancellationRequested)
break;
} while (true);
});
_canceller.Dispose();
goButton.Enabled = true;
stopButton.Enabled = false;
}
private void stopButton_Click(object sender, EventArgs e)
{
_canceller.Cancel();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句