2016-08-03 60 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()'の中から結果の 'Task'に' .Wait() 'を使います。 –

答えて

3

async void方法は非常に落胆し、問題の多くの場合、時間(例えばここ)記号です。

を返すので、awaitを呼び出すことができないため、呼び出し元はすべての作業が完了するのを待ってから次のステートメントに移ります。

Taskawaitを返して問題を解決する方法を変更してください。同期コンテキストからMoveAccountsAsyncを呼び出す場合は、Waitを使用して結果を待ちます。ただし、デッドロックを引き起こす可能性のある特定の条件(たとえば、ASP.NETアプリケーションの一部として実行される場合)では注意が必要です。

+0

私は子タスクを生成する別のタスクを作成する必要がありますか?次に、子タスクを待つのではなく、メインタスクが完了するのを待ちますか?申し訳ありませんが、これは初めてのスレッドでの作業です! – DavidC799

+0

'タスク'!=スレッド。待っているタスクを持っていても、そこに新しいスレッドがあるわけではありません。ちょうど起こっているいくつかの仕事があり、あなたはそれが終わるのを待っています。 – MarcinJuraszek

+0

おっと!それで私が正しいと言ったことは何ですか?私は試みました: 'Task.Run(()=> MoveAccountsAsync(theAccounts、room))。Wait();'呼び出し時、以前と同じ結果が... – DavidC799

関連する問題