任务并行库和TPL数据流允许指定最大并行度。该值是上限,而非保证。实际上,TPL将根据包括系统资源在内的多种因素确定实际的并行度,而不超过任何程序员指定的最大值。
是否有某种机制来确定TPL在某个时间点对并行度的选择?
我特别要求,因为我移植了一些相当复杂的代码来使用TPL Dataflow,整体吞吐量远远低于原始代码。我想看一下TPL为我做出的选择,以了解它为何慢得多。
答案 0 :(得分:3)
我遇到了与你非常相似的情况。我最终使用我的日志记录数据告诉我大致每分钟使用了多少线程。这给了我一个粗略的数字但不准确。
我不相信TPL可以让你对线程的使用进行遥测。如果你想更精确地实现一些东西,我建议在每个任务/线程中实现逻辑,以标记它开始的时间和完成时间的一些共享列表。这是一个如何开始接近它的例子。
public class DoSomeTPLWork
{
public static void Start()
{
List<int> numberList = Enumerable.Range(1, 1000).ToList();
Parallel.ForEach(numberList, number =>
{
ThreadTracking.ThreadStarted();
int square = number * number;
Console.WriteLine("Square of {0} is {1}", number, square);
ThreadTracking.ThreadFinished();
}
);
var threadInfo = ThreadTracking.GetThreadInfo();
}
}
public class ThreadTracking
{
private static ConcurrentBag<ThreadInfo> _threadInfo = new ConcurrentBag<ThreadInfo>();
public static void ThreadStarted()
{
var threadInfo = new ThreadInfo(Thread.CurrentThread.ManagedThreadId);
threadInfo.Start();
_threadInfo.Add(threadInfo);
}
public static void ThreadFinished()
{
var threadInfo = _threadInfo.Where(ti => ti.ThreadId == Thread.CurrentThread.ManagedThreadId && !ti.Complete).SingleOrDefault();
if(threadInfo != null)
{
threadInfo.Stop();
}
}
public static List<ThreadInfo> GetThreadInfo()
{
return _threadInfo.ToList();
}
}
public class ThreadInfo
{
public bool Complete { get; set; }
public int ThreadId { get; set; }
public DateTime? TimeStarted { get; set; }
public DateTime? TimeFinished { get; set; }
public ThreadInfo(int threadId)
{
ThreadId = threadId;
}
public void Start()
{
TimeStarted = DateTime.Now;
Complete = false;
}
public void Stop()
{
TimeFinished = DateTime.Now;
Complete = true;
}
}
使用这些数据,您可以通过添加一些查询数据的方法或只是在Excel中弹出数据来使用它来查看任何给定秒数的线程数。