2017-07-31 19 views
0

非同期メソッドを実行するタスクを作成しようとしていますが、awaitActionパラメータがタスクのコンストラクタに含まれていないか、Task.Factory.StartNewのパラメータに問題があります。非同期メソッドを実行するタスクを開始するC#

私のタスクをどのようにインスタンス化するかによって、私は異なる問題があります。私は7つの例を提供しました。

コード例:(タスク作成の7例)

private ConcurrentDictionary<int, Task> Tasks { get; set; } 
    private bool active = true; 

    private async Task StartTasks() 
    { 
     int numTasks = 5; 

     for(int i = 0; i < numTasks; i++) 
     { 
      //Task status is almost instantly "RanTocompletion" while work is still being done 
      Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Cannot await method group 
      Task task = new Task(await DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Task status is almost instantly "RanTocompletion" while work is still being done 
      Task task = new Task(async (object state) => await DoWork(state), "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Throws a "Start may not be called on a promise-style task." Exception 
      Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap(); 
      task.Start(); 

      //Task starts doing work after Start() is called, then throws a "Start may not be called on a promise-style task." Exception 
      Task task = new Task(DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Task starts doing work, but status is "WaitingForActivation 
      Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning); 

      //Throws a "Start may not be called on a promise-style task." Exception 
      Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap(); 

      //For checking up on tasks as work is done 
      Tasks.TryAdd(task.Id, Task); 
     } 
    } 

    private async Task DoWork(object state) 
    { 
     while (active) 
     { 
      await MakeHttpRequest(); 
      await DoSomethingCpuBound(); 
      //..etc 
     } 
     //do any cleanup and return 
    } 

ことがTaskCreationOptionsを提供していないので、私はTask.Run()を使用することはできません。これらのタスクは、日常的に実行されます。

非同期アクションを待つタスクを開始するにはどうすればよいですか?

+5

これはX-Yの問題のようです。あなたはXを解こうとしていて、Yは答えだと思っていますが、あなたはYのやり方を知らないので、あなたはそれについて尋ねています。代わりにXについて質問するほうがよいでしょう。あなたは私たちにXが何であるかを示すべきです。 – Enigmativity

+0

最後の手段として、 'Task.Factory.StartNew'の同期匿名デリゲートを作成し、' .GetAwaiter()。GetResult() 'を介して待つことができます。 – zerkms

+0

@Enigmativity私は掻いているウェブサイトからページをダウンロードするのに 'HttpClient'を使っています。長い遅延があるので、より多くのページを並列に引き出すことができます。これは機能しますが、タスクのステータスを確認できます。この非同期スレッドを実行すると、 'HttpClient'を待つ間にブロックされます。私はそれを解決しようとしています –

答えて

2

非同期アクションを待つタスクを開始するにはどうすればよいですか?

TAPでは、tasks are returned "hot"である。それはTaskCreationOptionsを提供していないので、私はTask.Run()を使用することはできません

private ConcurrentDictionary<int, Task> Tasks { get; set; } 
private async Task StartTasks() 
{ 
    for(int i = 0; i < 5; i++) 
    { 
    Task task = DoWork(null); 
    Tasks.TryAdd(task.Id, task); 
    } 
} 

を:だから、あなたは文字通りメソッドを呼び出し、それが返すタスクを維持する必要があります。これらのタスクは、日常的に実行されます。

TaskCreationOptionsは必要ありません。 The LongRunning flag is just a hint, and the thread pool will recover within a couple of seconds even if you don't specify that hint。しかし、あなたの仕事はの非同期なので、それは問題ではありません。最初のスレッドプールで実行する必要はありません。

+0

私は実際にあなたからの応答を得ることを光栄に思っています。 'The Task = DoWork(null);'は私が探していたものです。説明とリンクに感謝します。 –

関連する問題