2016-08-03 137 views
1

我的代碼在所有任務完成之前繼續執行。任務。完成任務之前任務完成

我看過其他有類似問題的人,但看不到任何明顯的東西!

static Task MoveAccountAsync(MoverParams moverParams) 
    { 
     return Task.Run(() => 
     { 
      Console.WriteLine("Moving {0}", moverParams.Account.Name); 
      moverParams.Account.Mover.RefreshRoom(); 
      moverParams.Account.Mover.PathfindTo(moverParams.Room); 
     }); 

    } 

static async void MoveAccountsAsync(List<Account> accounts, int room) 
    { 

     List<Task> theTasks = new List<Task>(); 

     foreach (Account account in accounts) 
     { 
      // Create a new task and add it to the task list 
      theTasks.Add(MoveAccountAsync(new MoverParams(account, room))); 
     } 

     await Task.WhenAll(theTasks); 
     Console.WriteLine("Finished moving."); 
    } 

然後簡單地從靜態的主稱之爲:

MoveAccountsAsync(theAccounts, room); 

幫助非常感謝!

乾杯,戴夫

+1

您無法等待'async void'方法。它是隨時可以忘記的。除了事件處理程序外,總是使用'async Task'。在Main()中使用'.Wait()'作爲結果的'Task'。 –

回答

3

async void方法是非常灰心,很多時候(例如這裏)問題的跡象。

因爲您不在等待您的方法調用(並且您不能等待await,因爲它返回void)調用方將不會等待所有工作完成,然後再轉到下一個語句。

改變你的方法返回Taskawait它來解決這個問題。如果您從同步上下文中調用MoveAccountsAsync(例如Main方法),請使用Wait來等待結果。但請注意,在某些情況下(例如,如果作爲ASP.NET應用程序的一部分運行)可能導致死鎖。

+0

所以我必須創建另一個產生子任務的任務?然後等待主任務完成而不是等待子任務?道歉這是我第一次使用線程! – DavidC799

+0

'任務'!=線程。有一個任務,你在等待並不意味着有一個新的線程。只是有一些正在發生的工作,而您正在等待它完成。 – MarcinJuraszek

+0

糟糕!那麼我說的是正確的?我試過:'Task.Run((=)=> MoveAccountsAsync(theAccounts,room))。Wait();'當調用時,但結果與之前一樣... – DavidC799