本来我写了使用线程和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错误。 –