在我的程序中,我正在使用for loop
启动button
,我想使用另一个button
来解决此问题。
例如:
private void button1_Click(object sender, EventArgs e)
{
for( int i = 0; i < var; i++)
{
//doing something
}
}
使用第二个按钮中断循环,
private void button2_Click(object sender, EventArgs e)
{
//breaking loop;
}
需要帮助:)
答案 0 :(得分:6)
在button2_Click()
方法中设置一个标记,并在button1_Click()
循环中进行检查。
为了处理Windows事件并允许button2_Click()
句柄在迭代时运行,请在循环中添加Application.DoEvents()
:
bool breakLoop = false;
private void button1_Click(object sender, EventArgs e)
{
breakLoop = false;
for( int i = 0; i < var && !breakLoop; i++)
{
//doing something
Application.DoEvents();
}
}
private void button2_Click(object sender, EventArgs e)
{
breakLoop = true;
}
答案 1 :(得分:0)
你不能这样做,因为button1_Click
事件处理程序中的循环将持有UI线程。您的用户界面将不会响应任何事件,显示沙漏图标,直到循环结束。这意味着在button2_Click
完成之前无法输入button1_Click
。
您需要使用在UI线程外部运行的东西替换事件处理程序中长时间运行的循环。例如,您可以使用Task
s,可以使用CancellationToken
(related Q&A)取消。{/ p>
答案 2 :(得分:0)
可以说,最好以某种形式使用线程和取消令牌,而不是Application.DoEvents()。像这样:
private CancellationTokenSource loopCanceller = new CancellationTokenSource();
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
try
{
for (int i = 0; i < 100; i++)
{
this.loopCanceller.Token.ThrowIfCancellationRequested(); // exit, if cancelled
// simulating half a second of work
Thread.Sleep(500);
// UI update, Invoke needed because we are in another thread
Invoke((Action)(() => this.Text = "Iteration " + i));
}
}
catch (OperationCanceledException ex)
{
loopCanceller = new CancellationTokenSource(); // resetting the canceller
Invoke((Action)(() => this.Text = "Thread cancelled"));
}
}, loopCanceller.Token);
}
private void button2_Click(object sender, EventArgs e)
{
loopCanceller.Cancel();
}