此文使用上文的案例,链接如下所示:
WPF从非UI线程中更新UI元素
添加一个按钮,用于点击时取消线程的执行:
声明一个 CancellationTokenSource 类型的对象,这个对象用于发送一个信号,如下所示:
private CancellationTokenSource tokenSource = null;
按钮点击时的方法代码如下所示,如果这个对象被实例了,那就发送一个取消的信号:
private void Button_Click1(object sender, RoutedEventArgs e)
{
if(tokenSource != null)
{
tokenSource.Cancel();
tokenSource = null;
}
}
在开始计算按钮的响应事件方法中实例 tokenSource对象:
在计算的方法中接收这个信号,处理方式如下所示:
完整的代码如下所示:
private void Calculator(int from, int to)
{
tmpJsValue = 0;
tmpEsValue = 0;
for (Int32 i = from; i < to; i++)
{
// 判断是否取消计算
if (tokenSource.IsCancellationRequested)
{
tmpEsValue = tmpJsValue = -1;
return;
}
if (i % 2 == 0) ++tmpEsValue;
else ++tmpJsValue;
}
}
Int32 tmpJsValue = 0;
Int32 tmpEsValue = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
this.btn.IsEnabled = false;
this.esValue.Text = "0";
this.jsValue.Text = "0";
tokenSource = new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(obj =>
{
Calculator(1, 1000000000);
Dispatcher.BeginInvoke(new Action(() =>
{
if (tmpEsValue < 0 || tmpJsValue < 0)
{
this.jsValue.Text = "取消计算成功!";
this.esValue.Text = "取消计算成功!";
}
else
{
this.esValue.Text = tmpEsValue.ToString();
this.jsValue.Text = tmpJsValue.ToString();
}
this.btn.IsEnabled = true;
}));
});
}
private CancellationTokenSource tokenSource = null;
private void Button_Click1(object sender, RoutedEventArgs e)
{
if(tokenSource != null)
{
tokenSource.Cancel();
tokenSource = null;
}
}
效果如下所示: