WPF异步模式是一个比较复杂的实现过程。不过我们在这篇文章中将会为大家介绍一下有关WPF异步模式简单的实现方法,方便大家理解。#t#
以WeatherForecast为例. 需求: 用户在窗体上点击一个按钮, 程序去网络上查询天气情况, 并把结果显示在窗体上. 网络查询是一个耗时任务, 在等待结果的同时, 用户将看到一个旋转的时钟动画表示程序正在查询.
WPF异步模式为:
窗口类MainWindow中有耗时函数: string FetchWeatherFromInternet().
窗口类MainWindow中包含一个函数 UpdateUIWhenWeatherFetched(string result), 用于把任务结果显示在界面上.
当用户点击按钮时, 在 btnFetchWeather_Click() 中,
如果是同步调用, 代码很简单, 如下:
- string result = this.
FetchWeatherFromInternet();- this.UpdateUserInterface( result );
现在需要异步执行, 稍微麻烦点, 需要用到3个delegate, 其中一个代表要执行的任务, 另一个代表任务结束后的callback, 还有一个代表交给UI执行的任务, 上述WPF异步模式代码被替换成如下:
- // 代表要执行的异步任务
- Func<string> asyncAction =
this.FetchWeatherFromInternet();- // 处理异步任务的结果
- Action<IAsyncResult> resultHandler =
delegate( IAsyncResult asyncResult )- {
- //获得异步任务的返回值, 这段代码必须
在UI线程中执行- string weather = asyncAction.
EndInvoke( asyncResult );- this.UpdateUIWhenWeatherFetched
( weather );- };
- //代表异步任务完成后的callback
- AsyncCallback asyncActionCallback =
delegate( IAsyncResult asyncResult )- {
- this.Dispatcher.BeginInvoke
( DispatcherPriority.Background,
resultHandler, asyncResult );- };
- //这是才开始执行异步任务
- asyncAction.BeginInvoke
( asyncActionCallback, null );- private void ForecastButtonHandler
(object sender, RoutedEventArgs e)- {
- this.UpdateUIWhenStartFetching
Weather();- //异步任务封装在一个delegate中,
此delegate将运行在后台线程- Func<string> asyncAction = this.
FetchWeatherFromInternet;- //在UI线程中得到异步任务的返回值,
并更新UI //必须在UI线程中执行 Action
<IAsyncResult> resultHandler =
delegate(IAsyncResult asyncResult)
{ string weather = asyncAction.EndInvoke
(asyncResult); this.UpdateUIWhenWeather
Fetched(weather); };- //异步任务执行完毕后的callback, 此callback
运行在后台线程上. //此callback会异步调用
resultHandler来处理异步任务的返回值.- AsyncCallback asyncActionCallback =
delegate(IAsyncResult asyncResult)- {
- this.Dispatcher.BeginInvoke
(DispatcherPriority.Background,
resultHandler, asyncResult);- };
- //在UI线程中开始异步任务, //asyncAction
(后台线程), asyncActionCallback(后台线程)
和resultHandler(UI线程) //将被依次执行- asyncAction.BeginInvoke(asyncAction
Callback, null);- }
- private string FetchWeatherFromInternet()
- {
- // Simulate the delay from network access.
- Thread.Sleep(4000);
- String weather = "rainy";
- return weather;
- }
- private void UpdateUIWhenStartFetching
Weather()- {
- // Change the status this.fetchButton.
IsEnabled = false;- this.weatherText.Text = "";
- }
- private void UpdateUIWhenWeatherFetched
(string weather)- {
- //Update UI text
- this.fetchButton.IsEnabled = true;
- this.weatherText.Text = weather;
- }
以上就是对WPF异步模式实现的简单方法介绍。