2014-03-14 37 views
0

我在這看到了一些帖子......但大多數人都是手動創建任務,而不是從API接收它。在for循環中啓動任務,然後在所有人上執行waitall

我有這樣的代碼

 Task[] tasks = new Task[companyCount]; 
     // start all threads 
     for(int i = 0; i < companyCount; i++) { 
      string input = GetNextCompanyRecord(i); 
      string token = GetUserToken(); 
      HttpClient client = GetHttpClient(); 
      StringContent content = CreateStringContent(input); 
      var x = client.PostAsync(companyUrlString, content).ConfigureAwait(continueOnCapturedContext: false); 
      tasks[i] = x; 
     } 
     Task.WaitAll(tasks); 

的目標是,我開始爲每個記錄任務在for循環中,然後當所有任務都開始......做一個爲WaitAll。我不能將x變量賦給任務數組。

PostAsync方法未返回任務。而是返回ConfiguredTaskAwaitable。但我的希望是我會得到任務,我將能夠將其添加到我的陣列,然後做一個waitall。

+3

刪除不必要的'.ConfigureAwait(continueOnCapturedContext:false)',你是金。 –

回答

5

只要做到這一點是這樣的:

Task<HttpResponseMessage>[] tasks = new Task<HttpResponseMessage>[companyCount]; 
for(int i = 0; i < companyCount; i++) 
{ 
    string input = GetNextCompanyRecord(i); 
    string token = GetUserToken(); 
    HttpClient client = GetHttpClient(); 
    StringContent content = CreateStringContent(input); 
    var x = client.PostAsync(companyUrlString, content); 
    tasks[i] = x; 
} 
Task.WaitAll(tasks); 

但是,也許更清潔的方法是這樣:

var tasks = 
    from i in Enumerable.Range(0, companyCount) 
    let input = GetNextCompanyRecord(i) 
    let token = GetUserToken() 
    let client = GetHttpClient() 
    let content = CreateStringContent(input) 
    select client.PostAsync(companyUrlString, content); 

Task.WaitAll(tasks.ToArray()); 

甚至更​​好的是:

using (var client = GetHttpClient()) 
{ 
    var tasks = 
     from i in Enumerable.Range(0, companyCount) 
     let input = GetNextCompanyRecord(i) 
     let token = GetUserToken() 
     let content = CreateStringContent(input) 
     select client.PostAsync(companyUrlString, content); 

    Task.WaitAll(tasks.ToArray()); 
} 
+0

美麗的代碼! –

+0

在完成WaitAll之後,現在您將如何從每個任務獲取所有的HttpResponseMessage? –

+1

@KnowsNotMuch - 在執行WaitAll之前,將任務分配給一個數組,然後等待該數組。然後,您可以使用相同的數組來檢索所有的響應消息。只需從每個任務中獲取「價值」即可。這裏重要的是你必須使用相同的任務。如果您嘗試使用'tasks'查詢,您將創建一組新的任務。 – Enigmativity

2

PostAsync返回Task(一Task<HttpResponseMessage>,要準確),但後來你打電話ConfigureAwait就可以了,它返回一個ConfiguredTaskAwaitable

嘗試首先獲取對任務的引用,然後調用ConfigureAwait

var task = client.PostAsync(companyUrlString, content); 
ConfiguredTaskAwaitable awaitable = task.ConfigureAwait(continueOnCapturedContext: false); 
tasks[i] = task; 

另外,還要考慮:

  • 刪除調用ConfigureAwait,因爲你似乎並不需要也無妨。
  • 如果您想在任務完成時檢索任務結果,請將您的陣列從Task[]更改爲Task<HttpResponseMessage>[]
+2

儘管缺乏解釋,但Enigmativity的答案要好得多,你應該接受他。 – dcastro

+0

好的。謝謝。我已經看到了你的答案,所以已經標記爲答案。 –