2017-07-31 107 views
0

我試圖創建將運行異步方法的任務,問題是,我不能awaitAction參數在任務的構造函數,或Task.Factory.StartNew的參數。C#啓動任務運行異步方法

根據我如何實例化我的任務,我有不同的問題。我已經提供了七個例子,並對各自在下面創建的問題發表了評論

示例代碼:(任務創建的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 
    } 

我不能使用Task.Run(),因爲不提供TaskCreationOptions。這些任務將在字面上運行。

如何啓動任務以等待異步操作?

+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"。所以你從字面上只需要調用該方法,並保持它的任務返回:

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); 
    } 
} 

我不能使用Task.Run(),因爲不提供TaskCreationOptions。這些任務將在字面上運行。

你不需要TaskCreationOptionsThe 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);'正是我在找的東西,謝謝你的解釋和鏈接。 –