在异步事件上写入控制台
Writing to Console on async event
我正在使用 WebClient
向服务器提交一组 HTTP 请求(顺序无关紧要)。
我不想发送请求,而是等待、发送、等待等等。我想发送尽可能多的请求,然后等待响应的到来,但是,当我需要写入控制台时,问题就出现了在特定请求完成后。
输出看起来不错,然后我开始收到多个请求消息,然后是一组 Responses/Errors,而不是请求消息后跟响应。
在每个块完成之前,是否有任何方法可以阻止任何其他控制台写入?
int currentRequest = 1;
for (int i = 0; i < requests.Count; i++) {
using (var webclient = new WebClient())
{
webclient.DownloadStringCompleted += (sender, e) =>
{
Console.WriteLine();
Info("Request: " + currentRequest + "/" + requests.Count);
if (e.Error == null) {
// Do something with e.Result
} else {
Console.WriteLine("Error: " + e.Error.Message);
}
currentRequest += 1;
};
webclient.DownloadStringAsync(new Uri("URL HERE"));
}
}
另一个注意事项:我觉得这不是我应该处理请求的方式(异步),如果我错了请纠正我。
Is there any way to block any other Console Writes until each block finishes?
是的,这就是 lock
的目的。
int currentRequest = 1;
Object lockObject = new Object();
for (int i = 0; i < requests.Count; i++) {
using (var webclient = new WebClient())
{
webclient.DownloadStringCompleted += (sender, e) =>
{
lock(lockObject)
{
Console.WriteLine();
...
currentRequest += 1;
}
};
webclient.DownloadStringAsync(new Uri("URL HERE"));
}
}
严格来说这不会阻塞其他 'console writes',但它确实序列化了每个响应的处理。
I don't feel like this is how I should be handling requests (asynchronously)
没错。您应该使用 await
, Task
and Parallel.ForEach
. I'm not going to write a full example because for handling URLS, there are way way way more complications than just the async. I recommend you also read about ServicePointManager.DefaultConnectionLimit
并理解为什么您的异步下载可能比您预期的要慢。
我正在使用 WebClient
向服务器提交一组 HTTP 请求(顺序无关紧要)。
我不想发送请求,而是等待、发送、等待等等。我想发送尽可能多的请求,然后等待响应的到来,但是,当我需要写入控制台时,问题就出现了在特定请求完成后。
输出看起来不错,然后我开始收到多个请求消息,然后是一组 Responses/Errors,而不是请求消息后跟响应。
在每个块完成之前,是否有任何方法可以阻止任何其他控制台写入?
int currentRequest = 1;
for (int i = 0; i < requests.Count; i++) {
using (var webclient = new WebClient())
{
webclient.DownloadStringCompleted += (sender, e) =>
{
Console.WriteLine();
Info("Request: " + currentRequest + "/" + requests.Count);
if (e.Error == null) {
// Do something with e.Result
} else {
Console.WriteLine("Error: " + e.Error.Message);
}
currentRequest += 1;
};
webclient.DownloadStringAsync(new Uri("URL HERE"));
}
}
另一个注意事项:我觉得这不是我应该处理请求的方式(异步),如果我错了请纠正我。
Is there any way to block any other Console Writes until each block finishes?
是的,这就是 lock
的目的。
int currentRequest = 1;
Object lockObject = new Object();
for (int i = 0; i < requests.Count; i++) {
using (var webclient = new WebClient())
{
webclient.DownloadStringCompleted += (sender, e) =>
{
lock(lockObject)
{
Console.WriteLine();
...
currentRequest += 1;
}
};
webclient.DownloadStringAsync(new Uri("URL HERE"));
}
}
严格来说这不会阻塞其他 'console writes',但它确实序列化了每个响应的处理。
I don't feel like this is how I should be handling requests (asynchronously)
没错。您应该使用 await
, Task
and Parallel.ForEach
. I'm not going to write a full example because for handling URLS, there are way way way more complications than just the async. I recommend you also read about ServicePointManager.DefaultConnectionLimit
并理解为什么您的异步下载可能比您预期的要慢。