【问题标题】:How to see how many thread is working to complete my task TPL?如何查看有多少线程正在工作以完成我的任务 TPL?
【发布时间】:2014-11-25 08:19:06
【问题描述】:

假设我想用任务并行库下载多个文件,现在我想可视化从 VS2010 IDE 调试时有多少线程在工作?这是一个使用 TPL 下载许多文件的代码 sn-p。

var list = new[] 
{ 
    "http://google.com", 
    "http://yahoo.com", 
    "http://stackoverflow.com" 
}; 

var tasks = Parallel.ForEach(list,
        s =>
        {
            using (var client = new WebClient())
            {
                Console.WriteLine("starting to download {0}", s);
                string result = client.DownloadString((string)s);
                Console.WriteLine("finished downloading {0}", s);
            }
        });

请指导我或将我重定向到我可以从中获取知识的任何文章,以查看正在运行多少线程来完成我的任务。

【问题讨论】:

  • 为什么这对你很重要?也更喜欢DownloadStringTaskAsync 而不是同步版本。因为操作本质上是异步的。
  • 如果您坚持使用 VS 2010 和 .NET 4.0,您应该考虑升级到免费的 Visual Studio 2013 社区(与 VS Pro 相同)并开始使用添加了DownloadStringTaskAsync 的 .NET 4.5 .即使您必须支持 XP(不运行 4.5),您也可以将 BCL Async 和 HttpClient 包添加到 VS 2013。
  • 这不清楚“即使您必须支持 XP(不运行 4.5),您也可以将 BCL Async 和 HttpClient 包添加到 VS 2013”​​您想说的话。跨度>

标签: c# .net multithreading task-parallel-library async-await


【解决方案1】:

Parallel.ForEach 将默认使用ThreadPool 作为其底层线程池,除非您在传递实例ParallelOptions(并传递自定义TaskScheduler)时另行指定。您可以通过用ThreadPool.GetAvailableThreads 减去ThreadPool.GetMaxThreads 来监视线程池并查看当前正在使用多少线程,但这将告诉您线程池当前正在使用许多线程,线程池不仅用于运行当前循环但您的程序中还有其他工作。

更具体地说,您可以使用Thread.CurrentThread.ManagedThreadId获取当前正在执行的ThreadId

using (var client = new WebClient())
{
    Console.WriteLine("Currently running on thread id: {0}",
                       Thread.CurrentThread.ManagedThreadId);
    Console.WriteLine("starting to download {0}", s);
    string result = client.DownloadString((string)s);
    Console.WriteLine("finished downloading {0}", s);
}

现在,作为您问题的旁注,执行 IO 绑定工作根本不需要使用线程,因为它本质上是异步的。这意味着使用Parallel.ForEach 可能会导致使用线程池线程来简单地阻塞挂起的 IO 请求的更多开销。

您可以做的是同时执行这些请求

string[] list = new[] 
{ 
    "http://google.com", 
    "http://yahoo.com", 
    "http://stackoverflow.com" 
}; 

using (WebClient client = new WebClient())
{
    var webRequestTasks = list.Select(address => client
                                                 .DownloadStringTaskAsync(address))
                                                 .ToList();
    await Task.WhenAll(webRequestTasks);
}

这样不会有阻塞线程,并且您的 HTTP 请求会同时执行。

【讨论】:

  • 我想知道 VS2010/2012 IDE 中是否存在任何可视化工具,可以帮助我查看当我从我的 IDE 执行上述代码时同时分配了多少线程来完成我的任务?跨度>
  • 您可以使用 Debug -> Windows -> Threads 查看当前正在运行的线程,如果你设置了一个断点。但它不会为你总结线程。
  • 有什么好的免费可视化工具。如果您知道,请分享名称和网址....所以我可以下载它。谢谢
  • 可以使用Visual Studio的Concurrency Visualizer
猜你喜欢
  • 2017-12-16
  • 1970-01-01
  • 2014-09-17
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多