为什么这个代码在通过TPL / Tasks执行时会失败?

我正在使用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中,但对于我的生活,我在代码中看不到任何共享状态。 有没有人有任何想法?

谢谢,埃里克

我终于找到了这个问题。 问题是HttpClient发布了自己的附加任务,因此我启动的单个任务实际上可能会产生5个或更多任务。

调度程序配置了对任务数量的限制。 我启动了任务,导致运行任务的数量达到最大限制。 然后HttpClient尝试启动自己的任务,但由于达到了限制,它会阻塞,直到任务数量下降,这当然从未发生过,因为他们正在等待我的任务完成。 你好死锁。

故事的道德:

  1. 任务可能是全球资源
  2. 任务之间通常存在非明显的相互依赖关系
  3. 调度程序不容易使用
  4. 不要假设您控制调度程序或任务数量

我最终使用另一种方法来限制连接数。

埃里克