我正在使用System.Net.Http来使用网络资源。在单个线程上运行时,它可以完美运行。当我通过TPL运行代码时,它会挂起并永远不会完成,直到达到超时。
所发生的是所有线程最终都在sendTask.Result行上等待。我不确定他们在等什么,但我认为它是HttpClient中的东西。
网络代码是:
using (var request = new HttpRequestMessage(HttpMethod.Get, "http://google.com/"))
{
using (var client = new HttpClient())
{
var sendTask = client.SendAsync
(request, HttpCompletionOption.ResponseHeadersRead);
using (var response = sendTask.Result)
{
var streamTask = response.Content.ReadAsStreamAsync();
using (var stream = streamTask.Result)
{
// problem occurs in line above
}
}
}
}
我使用的TPL代码如下。 Do方法完全包含上面的代码。
var taskEnumerables = Enumerable.Range(0, 100);
var tasks = taskEnumerables.Select
(x => Task.Factory.StartNew(() => _Do(ref count))).ToArray();
Task.WaitAll(tasks);
我已经尝试了几种不同的调度程序,我可以让它工作的唯一方法是编写一个调度程序,将运行任务的数量限制为2或3.但是,有时甚至会失败。
我认为我的问题出现在HttpClient中,但对于我的生活,我在代码中看不到任何共享状态。有没有人有任何想法?
谢谢, 埃里克
答案 0 :(得分:2)
我终于找到了这个问题。问题在于HttpClient发布了自己的附加任务,因此我启动的单个任务实际上可能会产生5个或更多任务。
调度程序配置了对任务数量的限制。我启动了任务,导致运行任务的数量达到最大限制。然后HttpClient尝试启动自己的任务,但由于达到了限制,它会阻塞,直到任务数量下降,当然从未发生过,因为他们正在等待我的任务完成。你好死锁。
故事的道德:
我最终使用另一种方法来限制连接数。
埃里克