Windows 8 學習筆記(十七)--.WinRT 異步編程


我們知道,在WinRT中很多接口都是異步的,如StorageFileMediaCapture等。它們都是以“Async”結尾。那使用異步編程有什么好處呢?估計大家都知道,當我們執行一個函數需要花費數秒鍾,若使用同步方法,則會阻止UI線程,應用將不會響應用戶操作,體驗性將會非常糟糕。而使用異步編程,應用在等待完成時可以繼續運行並響應UI

WinRT中,每種語言都有其異步編程的模式:

JavaScript :   承諾對象,then函數

C#:  將來對象,await運算符

VB:  將來對象,await運算符

Visual C++:  task類,.then方法

WinRT 異步編程(C#

WinRT中的C#異步編程相對較簡單,需要遵守幾個規則:

(1)      調用異步API的方法體前需要以async標識

(2)      調用異步API需要使用await運算符

Await運算符你可將其看作它告訴編譯器當前正在調用某個異步方法,編譯器可以執行其它的工作,無需在此等待。作用await運算符的好處是代碼看上去不復雜,又易於理解和維護。

private async  void CreateFile()
        {
            StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
            StorageFile storageFile = await storageFolder.CreateFileAsync( " template.txt ",CreationCollisionOption.ReplaceExisting);
            OutputTextBlock.Text = storageFolder.Name +  " has been created "

              }

 

 WinRT 異步編程(C++

C++異步編程相對C#較復雜些,主要通過ppltask.h中定義的任務類來使用異步方法。

C++中直接使用異步WinRT API時,首選task類及其相關類型和函數,它們都包含在concurrency命名空間中,並且在ppltask.h中定義。

(1)      利用create_task創建一個任務

auto createFileTadk =create_task(folder->CreateFileAsync("aa.txt",CreationCollisionOption::ReplaceExisting));

    (2)      利用task::then實現異步完成時所執行的操作

 

   createFileTadk.then([ this ](StorageFile^ storageFileSample) {  
         String^ filename=storageFileSample->Name;                              
        });   

       

task::then函數創建並返回的任務稱為延續,異步工作成功完成后才會運行。若異步操作引發異常,或取消任務,則延續永遠不會執行。以上是一個很簡單的異步示例,在延續任務中沒有異步任務,若在延續中我們還會再次執行異步任務,可能異步任務的延續中還會再有異步任務,這一系列的任務就會形成一個任務鏈,一環接一環,每個延續只有在前一個延續任務完成后才會執行,這就會形成這樣一種形式:mytask.then().then().then();

如上例操作,我需要在創建文件后,還得往文件寫入內容,寫完文件我還得給用戶一個提示:

 

     createFileTadk.then([ this ](StorageFile^ storageFileSample) ->IAsyncAction^ {       
    String^ userContent= " abcdwfwe ";
    create_task(FileIO::WriteTextAsync(storageFileSample, userContent)).then([ this, storageFileSample, userContent]()
                {
        MessageDialog^ message= ref  new MessageDialog( " File is completed create! ");
        message->ShowAsync();
                });    
    });

 

     捕獲異步任務的異常

我們可以通過task::get獲取任務結果,其可以獲取已經傳輸到該任務的所有。

  createFileTadk.then([ this ](StorageFile^ storageFileSample) ->IAsyncAction^ {     
        String^ userContent= " abcdwfwe ";    
         return FileIO::WriteTextAsync(storageFileSample, userContent);
    }).then([](task< void> t){
         try
        {
            t. get();            
            OutputDebugString(L " the content has been write into file! ");
             // tbText->Text="the content has been write into file";
        }
         catch(Platform::COMException^ e)
        {
            
        }
    });

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM