2016-11-07 69 views
4

我在C#中掙扎着多線程(我只是爲了好玩而學習),並意識到我可能不明白線程是什麼!當我運行下面的代碼時,我期待得到類似以下輸出的內容。ThreadLocal <T> - 什麼是線程? (C#)

T1: 11 
T2: 11 
T3: 11 
T4: 11 
T5: 11 
T6: 11 

(以不同的順序可能)

但是,我越來越像

T1: 11 
T2: 11 
T3: 12 
T5: 12 
T6: 13 
T4: 11 

我曾以爲,每個任務(T1到T6),將是一個新的線程,因此「本地」的每個實例將被初始化爲10並遞增1。但它看起來並不像這樣。如果任何人都可以解釋發生了什麼以及我錯誤地假設了什麼,我會非常感激。 (我必須承認,我發現它來與線程交手很困難,因爲我無法找到任何東西基本夠用,從開始!)

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace TestThreads 
{ 

    class TestThreadLocal 
    { 

     static void Main() 
     { 
      ThreadLocal<int> local = new ThreadLocal<int>(() => 
      { return 10; 
      }); 

      Task t1 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T1: " + local.Value); 
      }); 

      Task t2 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T2: " + local.Value); 
      }); 
      Task t3 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T3: " + local.Value); 
      }); 

      Task t4 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T4: " + local.Value); 
      }); 

      Task t5 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T5: " + local.Value); 
      }); 

      Task t6 = Task.Run(() => 
      { local.Value++; 
       Console.WriteLine("T6: " + local.Value); 
      }); 

      Task.WaitAll(t1, t2, t3, t4, t5, t6); 
      local.Dispose(); 
     } 
    } 
} 
+9

任務!=線程。其中一個主要任務是分配工作單元和*不關心線程細節,以瞭解它們的運行方式 –

+3

我的猜測是,因爲Task.Run使用**線程池**,所以有些任務在運行同一個線程,如果這個線程已經設法完成前面的任務。 –

+2

https://msdn.microsoft.com/en-us/library/dn906268(v=vs.110).aspx –

回答

3

原因是Task.Run使用線程池,這意味着它抓住一些來自已有線程池的免費線程,對其起作用,並且將其返回(以簡化的方式)。所以很可能一個或多個後續的Tas.Run操作將在同一個線程上運行。最簡單的方法來驗證它是打印當前線程ID:

Task.Run(() => { 
    local.Value++; 
    Console.WriteLine("Thread id: {0}, value: {1}", Thread.CurrentThread.ManagedThreadId, local.Value); 
} 
+0

感謝Evk - 這是非常有意義的,並且有明確的解釋。這正是我需要知道的。也感謝關於添加線程ID的提示,因爲它使得它更清晰。 – HedgePig