2013-06-18 57 views
1

如何在不阻塞線程的情況下在SubmitWorkitem()方法後執行UpdateTasklist()方法?等待異步方法不阻塞線程

private async void SubmitWorkitem(Workitem workitem) 
{ 
    await Task.Run(() => this.SubmitWorkitem(workitem)); 

    //UpdateTasklist() should be executed after SubmitWorkitem() method. 
    //How can i achieve this without blocking the UI thread? 
    var locator = new ViewModelLocator(); 
    locator.Task.UpdateTasklist(); 
} 

編輯:

UpdateTasklist()方法連接到一個WCF Web服務,並要求所有打開的工作項。在SubmitWorkitem()方法中提交的工作項目仍然是答覆的一部分。我認爲這將是因爲UpdateTasklist()在提交工作項目完成之前執行。

注意UpdateTasklist()也是異步方法

+0

要麼定義回調,或把'UpdateTaskList'放在異步任務 –

+0

編輯我的答案編輯 –

+2

哦,只是注意到,這是'async void';是的...不要那樣做;那簡直是危險的。該特性* only *存在以允許事件處理程序;你絕對不應該選擇「異步無效」方法;它應該是'異步任務'或'異步任務' –

回答

4

重要:請勿填寫ASYNC VOID方法(除非你正在編寫一個事件處理程序)

對於剩下:

這已經是你的代碼發生了什麼;這是什麼await意味着;基本上,您的DifferentClass.UpdateTasklist();方法作爲延續的一部分發生,第一個任務(this.SubmitWorkitem(workitem))完成時會被調用。

隨着你的編輯,有缺少的一步:你應該await第二種方法,否則該方法不能報告完成/失敗(IIRC編譯器也會嘮叨你):

private async Task SubmitWorkitem(Workitem workitem) 
{ 
    await Task.Run(() => this.SubmitWorkitem(workitem)); 
    var locator = new ViewModelLocator(); 
    await locator.Task.UpdateTasklist(); 
} 
+0

該方法必須是無效的,因爲:this.SubmitCommand = new RelayCommand(this.SubmitWorkitem,this .CanSubmit); – Joel

+3

@Joel嗯,我想這必須與事件處理程序在相同的括號下;也許正確的指導是「不要寫一個異步無效方法,除非你別無選擇」 - 但是,請記住,這裏的跑步者將不知道你的方法是否已經完成 - 就框架而言,該方法會在它到達第一個「await」的時候「超過」(如果我們假設等待的操作實際上並未完成同步,這可能發生,但這聽起來不太可能)。問題的關鍵在於...可能會遇到麻煩 –

+2

@Joel:在這種情況下,您確實需要一個'異步無效'ICommand.Execute'實現,但您可以將其隱藏在「異步任務」方法後面。這爲您提供了一個更好的API,您可以直接使用它,例如單元測試時。一個簡單的'AsyncCommand'類型是[here](http://stackoverflow.com/a/15743118/263693),我寫了一個更復雜的[這裏](https://nitoasyncex.codeplex.com/SourceControl/latest#源極/ Nito.AsyncEx.Mvvm%20(NET45,%20Win8,%20SL4,%20WP75)/AsyncCommand.cs)。 –