在现代应用程序开发中,异步编程模式(Async/Await)是提高应用程序响应性的关键技术之一。本文将介绍如何在基于WPF的简单应用程序中使用异步/等待模式,并展示用户如何通过CancellationToken取消当前启动的线程。
应用程序界面非常简单。用户输入文本文件的完整路径,点击“获取”按钮,文本文件的内容将加载到主屏幕上(如果找到的话),否则会显示错误消息。为了证明文本文件的处理(读取)是异步执行的,用户可以在处理输入文件时点击“+”按钮。这将在主屏幕上显示一个递增的整数值。在处理文件时,主屏幕上会显示一个%处理消息。最后,为了展示CancellationToken的使用,当用户点击“取消”按钮时,正在运行的线程(任务)将被中断,并向用户显示取消消息!
注意事项1:使用区域 认为将相似的代码分组到区域中总是一个好主意,通常使用以下区域:
注意事项2:在UI代码后编写代码 为了简单起见...这个示例中的所有事件处理和应用程序逻辑都写在了主窗体的代码后。虽然这对于演示目的是可以的,但在生产编码中应该避免。相反,所有应用程序和事件处理逻辑应该从UI代码后提取出来,放入所谓的ViewModel类中,适应MVVM(Model-View-ViewModel)模式。
#region Private Storage
private int _counter;
CancellationTokenSource _cts;
#endregion Private Storage
_counter变量将用于更新用户点击+按钮时的计数器。这只是为了向读者展示UI界面在后台线程运行(任务执行用户激活Get按钮后的异步读取)时保持响应。
private async void buttonGetFile_Click(object sender, RoutedEventArgs e)
{
try
{
_cts = new CancellationTokenSource();
textBlockResult.Text = string.Empty;
labelPlus.Content = string.Empty;
labelProgress.Content = string.Empty;
buttonGetFile.IsEnabled = false;
textBlockResult.Text = await GetFileContentAsync(textBoxFileName.Text, _cts.Token);
}
catch (OperationCanceledException exCancel)
{
MessageBox.Show(exCancel.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
buttonGetFile.IsEnabled = true;
}
}
此方法将调用一个以异步方式从文件中读取数据的方法。在调用GetFileContentAsync(...)时,将_cts的CancellationTokenSource.Token属性作为参数传递。Token属性在请求取消时传播取消消息。添加一个catch块,如果用户选择取消文件读取操作,则显示消息。当此IO绑定的后台线程运行时,UI仍然可以响应用户输入(点击+按钮以证明这一点)。
private void buttonPlus_Click(object sender, RoutedEventArgs e)
{
labelPlus.Content = _counter++.ToString();
}
在后台线程执行期间(当用户提供了正确的本地磁盘物理文件的URL并点击UI中的Get按钮启动IO绑定的检索过程时),UI保持响应,用户可以点击+按钮,这将增加计数器。