在异步事件上写入控制台

时间:2017-01-07 15:36:59

标签: c# asynchronous webclient

我正在使用WebClient向服务器提交一组HTTP请求(顺序并不重要)。

而不是发送请求,等待,发送,等待等等。我想尽可能多地发送并等待响应,但是,当我需要写入控制台后出现问题具体要求已经完成。

输出看起来很好,然后我开始获得多个请求消息,然后是一组响应/错误,而不是请求消息,然后是响应。

在每个块完成之前,有没有办法阻止任何其他控制台写入?

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

另一个注意事项:我不觉得我应该如何处理请求(异步),如果我错了,请纠正我。

1 个答案:

答案 0 :(得分:1)

  

在每个块完成之前,有没有办法阻止任何其他控制台写入?

是的,这是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"));
    }
}

严格来说,这不会阻止其他控制台写入,但它会对每个响应的处理进行序列化。

  

我不觉得这是我应该如何处理请求(异步)

这是事实。您应该使用awaitTaskParallel.ForEach。我不打算写一个完整的例子,因为对于处理URLS,有一种方法比仅仅异步更复杂。我建议您也阅读ServicePointManager.DefaultConnectionLimit并了解为什么您的下载异步可能比您预期的要慢。