• WPF 简单异步模式


    以WeatherForecast为例. 需求: 用户在窗体上点击一个按钮, 程序去网络上查询天气情况, 并把结果显示在窗体上. 网络查询是一个耗时任务, 在等待结果的同时, 用户将看到一个旋转的时钟动画表示程序正在查询.

    模式为:

    1. 窗口类MainWindow中有耗时函数: string FetchWeatherFromInternet().
    2. 窗口类MainWindow中包含一个函数 UpdateUIWhenWeatherFetched(string result), 用于把任务结果显示在界面上.
    3. 当用户点击按钮时, 在 btnFetchWeather_Click() 中,

      如果是同步调用, 代码很简单, 如下:
      string result = this.FetchWeatherFromInternet();
      this.UpdateUserInterface( result );

      现在需要异步执行, 稍微麻烦点, 需要用到3个delegate, 其中一个代表要执行的任务, 另一个代表任务结束后的callback, 还有一个代表交给UI执行的任务, 上述代码被替换成如下:

      // 代表要执行的异步任务
      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.UpdateUIWhenStartFetchingWeather();
    
        //异步任务封装在一个delegate中, 此delegate将运行在后台线程 
        Func<string> asyncAction = this.FetchWeatherFromInternet;
    
     

    //在UI线程中得到异步任务的返回值,并更新UI
    //必须在UI线程中执行


    Action<IAsyncResult> resultHandler =

    delegate(IAsyncResult asyncResult)
    {
    string weather = asyncAction.EndInvoke(asyncResult);
    this.UpdateUIWhenWeatherFetched(weather);
    };

     
        //异步任务执行完毕后的callback, 此callback运行在后台线程上. 
    //此callback会异步调用resultHandler来处理异步任务的返回值.
    AsyncCallback asyncActionCallback = delegate(IAsyncResult asyncResult) { this.Dispatcher.BeginInvoke(DispatcherPriority.Background, resultHandler, asyncResult); }; //在UI线程中开始异步任务,
    //asyncAction(后台线程), asyncActionCallback(后台线程)和resultHandler(UI线程)
    //将被依次执行
    asyncAction.BeginInvoke(asyncActionCallback, null); } private string FetchWeatherFromInternet() { // Simulate the delay from network access. Thread.Sleep(4000); String weather = "rainy"; return weather; } private void UpdateUIWhenStartFetchingWeather() { // 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; }
  • 相关阅读:
    通过url在两个页面之间传值
    $.ajax数据传输成功却执行失败的回调函数
    5.26小测
    洛谷——AC记
    7.2模拟赛
    6.30模拟赛
    洛谷——每日一题
    洛谷——动态规划
    致创营
    BSGS
  • 原文地址:https://www.cnblogs.com/mrfangzheng/p/1390115.html
Copyright © 2020-2023  润新知