Windows store app[Part 4]:深刻WinRT的異步機制

接上篇Windows store app[Part 3]:認識WinRT的異步機制html

WinRT異步機制回顧:web

IAsyncInfo接口:WinRT下異步功能的核心,該接口提供全部異步操做的基本功能,如標識、狀態、操做。編程

 IAsyncInfo:windows

1 public interface IAsyncInfo
2 {
3     AsyncStatus Status { get; }
4     HResult ErrorCode { get; }
5     uint Id { get; }
6 
7     void Cancel();
8     void Close();
9 }

IAsyncInfo沒有定義當操做完成時,通知監聽器的回調方法的功能。從上篇能夠知道基於IAsyncInfo有四個子接口。app

這四個子接口對上述功能進行了定義。異步

Dispatcher的變化:async

在WPF應用程序中經過Dispathcer.BeginInvoke通知UI線程進行異步操做。WinRT中摒棄了這種方式。ui

咱們來看下WinRT的新變化。spa

ThreadPool有一個RunAsync方法,參數是Worker項(要耗時作處理的工做)線程

1 public static IAsyncAction RunAsync(WorkItemHandler handler);

在UI線程中實現:

 1 private void btnDoWork_Click(object sender, RoutedEventArgs e)
 2 {
 3     int result = 0;
 4     var op = ThreadPool.RunAsync(delegate { result = Compute(); })
 5     op.Completed = delegate(IAsyncAction asyncAction, AsyncStatus asyncStatus)
 6     {
 7         Dispatcher.RunAsync(CoreDispatcherPriority.Normal, delegate
 8         {
 9             switch (asyncStatus)
10             {
11                 case AsyncStatus.Completed:
12                     btnDoWork.Content = result.ToString();
13                     break;
14                 case AsyncStatus.Error:
15                     btnDoWork.Content = asyncAction.ErrorCode.Message;
16                     break;
17                 case AsyncStatus.Canceled:
18                     btnDoWork.Content = "A task was canceled";
19                     break;
20             }
21         });
22     };
23 }

ThreadPool執行完成時調用Completed的處理方法通知UI線程更新,這裏使用Dispathcher.RunAsync與WPF程序中Dispatcher.BeginInvoke功能相同。

固然這樣的寫法在WinRt中能夠更簡化,經過async/await關鍵字,咱們把處理完成的回調操做交給WinRT去處理,從而不須要手動Code去處理回調操做。這種寫法簡化在處理連續執行多個異步操做時所需Code的大量代碼。示例:

 1 private async void btnDoWork_Click(object sender, RoutedEventArgs e)
 2 {
 3     try
 4     {
 5         int result = 0;
 6         await ThreadPool.RunAsync(delegate { result = Compute(); });
 7         btnDoWork.Content = result.ToString();
 8     }
 9     catch (Exception exc) { btnDoWork.Content = exc.Message; }
10 }

使用Async關鍵字帶來的擴展

使用Async關鍵字標記方法時,編譯器會使用狀態機從新編寫該方法的實施。關於編譯器的處理方法能夠參閱MSDN,async關鍵字編譯器轉換的相關內容。

在WinRT編程中咱們有時但願一個方法的操做不是異步,而是同步的。這時咱們能夠經過WinRT提供的Task任務類將其轉換爲任務並獲取處理結果。如:

1 var files = StorageFolder.GetFilesAsync().AsTask().Results;

或者

1 var files = StorageFolder.GetFilesAsync().AsTask().GetAwaiter()

這樣就能夠實現直接等待WinRt異步操做的結果,而不使用Async/Await。
AsTask還支持取消操做(CancellationToken )、進度(IProgress<T> ),經過ContinueWith實現任意屢次的回調。其中

還包括WhenAll WhenAny 操做,能夠經過MSDN瞭解其用途。

 

至此咱們已經瞭解了WinRT的內部操做機制。若是對其瞭解還不夠透徹,提供如下Windows開發人員官方博客進行釋疑,但願能幫到你們理解這些概念。

Link:

將.NET 任務做爲WinRT異步操做公開

使用Windows運行時中異步性來始終保持應有程序可以快速流暢地運行

深刻探究WinRT和await

 

下篇:Windows store app[Part 5]:WinRT的反射機制 

相關文章
相關標籤/搜索