如何跟踪.Net线程池使用情况? [英] How to track .Net thread pool usage?

查看:76
本文介绍了如何跟踪.Net线程池使用情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AFAIK .Net库中的某些方法能够异步执行 I/O作业,而不会占用池中的线程.

AFAIK some methods in the .Net library are able to do I/O jobs asynchronously without consuming a thread from the pool.

如果我的信息正确,则 WebClient *异步方法可以做到这一点.

If my information are correct the WebClient *Async methods do that.

我想通过检查下载期间未有效使用池中的线程来进行验证.

I'd like to verify it by checking that effectively threads from the pool are not used during a download.

所以我的一般问题是:如何监视线程​​池的当前状态?

So my general question is : how can I monitor the current state of the thread-pool?

  • 线程数

  • number of threads

繁忙线程数

是否有一些 API ( GetAvailableThreads ?)或性能计数器会提供此信息?

Is there some API (GetAvailableThreads?) or performance counters that would give this information?

这里有更多详细信息

我正在为教育目的编写一个简单的基准测试

I'm writing a simple benchmark for educational purposes:

string[] urls = Enumerable.Repeat("http://google.com", 32).ToArray();
/*{
    "http://google.com",
    "http://yahoo.com",
    "http://microsoft.com",
    "http://wikipedia.com",
    "http://cnn.com",
    "http://facebook.com",
    "http://youtube.com",
    "http://twitter.com"
};*/

/*Task.Run(() =>
    {
        while (true)
        {
            int wt, cpt;
            ThreadPool.GetAvailableThreads(out wt, out cpt);
            Console.WriteLine("{0} / {1}", wt, cpt);
            Thread.Sleep(100);
        }
    });*/

WebClient webClient = new WebClient();
Stopwatch stopwatch = Stopwatch.StartNew();
foreach (string url in urls)
{
    webClient.DownloadString(url);
    Console.WriteLine("Got '{0}'", url);
}
stopwatch.Stop();

TimeSpan sequentialTime = stopwatch.Elapsed;

stopwatch.Restart();
CountdownEvent cde = new CountdownEvent(1);
foreach (string url in urls)
{
    cde.AddCount();
    webClient = new WebClient();
    webClient.DownloadStringCompleted += (_, __) =>
    {
        Console.WriteLine("Got '{0}'", __.UserState);
        cde.Signal();
    };
    webClient.DownloadStringAsync(new Uri(url), url);
}
cde.Signal();
cde.Wait();
stopwatch.Stop();

TimeSpan asyncTime = stopwatch.Elapsed;

stopwatch.Restart();
ThreadLocal<WebClient> threadWebClient = new ThreadLocal<WebClient>(() => new WebClient());
urls.AsParallel().WithDegreeOfParallelism(urls.Length).ForAll(url => threadWebClient.Value.DownloadString(url));
stopwatch.Stop();

TimeSpan PLinqTime = stopwatch.Elapsed;

Console.WriteLine("Sequential time: {0}.", sequentialTime);
Console.WriteLine("PLinq time: {0}.", PLinqTime);
Console.WriteLine("Async time: {0}.", asyncTime);

我正在比较:

  • 天真顺序循环
  • PLINQ 循环
  • 异步I/O

有趣的是最后两个.

我希望并尝试证明异步I/O是:

I expect and try to prove that async I/Os are:

  • 更快,因为它们将对池造成更少的压力(需要创建更少的线程...)

  • faster because they will create less pressure on the pool (less threads need to be created...)

更轻,因为它们将消耗池中更少的线程

lighter because they will consume less thread of the pool

我的基准"表明速度更快,我想这是因为池不需要为每个请求分配新线程,而使用PLINQ,每个并行请求将阻塞一个线程.

My "benchmark" shows that it's faster and I guess that's because the pool does not need to allocate new threads for each request whereas with PLINQ each parallel request will block one thread.

现在,我想检查有关线程消耗的数字.

Now I'd like to check the numbers about thread consumption.

评论的任务是监视池的不良尝试.也许这是一个很好的起点,但是直到现在结果还与我的预期并不完全一致:它永远不会显示消耗了超过3/4的线程,而我希望有32个线程在忙.

The commented task was a poor attempt to monitor the pool. It may be the good starting point but until now the result are not really consistent with what I expect: it never displays that more than 3/4 threads are consumed, whereas I expect something like 32 threads busy.

我愿意提出任何增强或改进其他用例的想法,这些用例将清楚地突出这两种方法之间的差异.

I'm open to any idea to enhance it or better any other use-case that would clearly highlight the differences between the two approaches.

希望现在可以更清楚地了解这一点,对于未能尽快提供详细信息,我们深表歉意.:)

Hope this is clearer now, and sorry for not having provided the details sooner. :)

推荐答案

ThreadPool类提供了GetAvailableThreads方法,该方法检索GetMaxThreads方法返回的最大线程池线程数与当前活动的线程数之间的差".[1]: http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.getavailablethreads%28v=vs.110%29.aspx

The ThreadPool class provides the GetAvailableThreads method which "Retrieves the difference between the maximum number of thread pool threads returned by the GetMaxThreads method, and the number currently active." [1]: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getavailablethreads%28v=vs.110%29.aspx

您可以轻松地捕获比率:

You can capture the ratio thustly:

        int workerThreads;
        int completionPortThreads;
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        Console.WriteLine("{0} of {1} threads available", workerThreads, completionPortThreads);

这篇关于如何跟踪.Net线程池使用情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆