2012-10-31 46 views
4

任務並行庫和TPL數據流允許指定最大並行度。這個價值是一個上限,而不是一個保證。事實上,TPL將根據包括系統資源在內的多個因素確定實際並行度,而不會超出程序員指定的最大值。測量TPL中的並行度

是否有一些機制來確定TPL在某個時間點對並行度的選擇?

我在問具體問題,因爲我移植了一些相當複雜的代碼來使用TPL Dataflow,並且整體吞吐量遠遠低於原始代碼。我想看看TPL代表我選擇了什麼選擇來理解它爲什麼要慢得多。

+0

我認爲沒有什麼內置的,但你應該可以通過添加你自己的日誌來做到這一點。 – svick

+0

@svick:記錄什麼?我嘗試創建一個HashSet ,它的管理線程ID是'但是發現MaximumDegreeOfParallelism說的2最終在5個不同的線程上運行(這是我期望的)。 –

+0

您可以在任務開始時遞增計數器,然後在完成時遞減計數器。計數器的價值就是當前的並行度,你可能會對它達到的最高價值感興趣。但它也可能更復雜一些。 – svick

回答

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中發揮它給出。