本來我寫了使用線程和ThreadPooling我的C#程序,但大多數在這裏的用戶都告訴我異步是爲了提高效率的更好方法。我的程序將JSON對象發送到服務器,直到返回狀態代碼200,然後轉到下一個任務。如何讓任務更獨立?
的問題是,一旦我的任務之一取回的200狀態碼,它等待其它任務,以獲得200碼,然後移動到下一個任務。我希望每個任務都能夠繼續執行下一個任務,而無需等待其他任務通過接收200響應來完成(或趕上)任務。
下面是我的並行運行我的任務主類。
public static void Main (string[] args)
{
var tasks = new List<Task>();
for (int i = 0; i < 10; i++) {
tasks.Add (getItemAsync (i));
}
Task.WhenAny (tasks);
}
這是實際發送信息到另一臺服務器的getItemAsync()方法。在此方法起作用之前,它需要一個密鑰。問題也出在這裏,假設我運行了100個任務,所有100個任務都會等到每個人都擁有一個密鑰。
public static async Task getItemAsync (int i)
{
if (key == "") {
await getProductKey (i).ConfigureAwait(false);
}
Uri url = new Uri ("http://www.website.com/");
var content = new FormUrlEncodedContent (new[] {
...
});
while (!success) {
using (HttpResponseMessage result = await client.PostAsync (url, content)) {
if (result.IsSuccessStatusCode) {
string resultContent = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
Console.WriteLine(resultContent);
success=true;
}
}
}
await doMoreAsync (i);
}
下面是檢索鍵的功能,它使用的HttpClient和被解析。
public static async Task getProductKey (int i)
{
string url = "http://www.website.com/key";
var stream = await client.GetStringAsync (url).ConfigureAwait(false);
var doc = new HtmlDocument();
doc.LoadHtml (stream);
HtmlNode node = doc.DocumentNode.SelectNodes ("//input[@name='key']") [0];
try {
key = node.Attributes ["value"].Value;
} catch (Exception e) {
Console.WriteLine ("Exception: " + e);
}
}
在每個任務收到一個密鑰並具有200狀態碼後,它將運行doMoreAsync()。我希望任何檢索200代碼的單個Task都能夠運行doMoreAsync(),而無需等待其他任務趕上。我如何去做這件事?
感謝您的回覆,我幾分鐘前發現了ContinueWith,現在我正在測試該方法。它不斷返回相同的線程#。和var finishedTask =等待tasks.WhenAny()不起作用。它說「System.Collections.Generic.list」不包含「whenany」的定義。 –
我的意思是'等待Task.WhenAny(任務);'這將等待列表中的一個任務完成。您可以在完成後從列表中刪除該任務。 另外任務不會映射到線程1:1。一堆任務可以在同一個線程內執行。任務可以在另一個人等待某件事情時執行。 –
是的,它不在我的主要工作。它扔我system.collections.generic.list錯誤。 –