2014-02-07 121 views
0

這是我第一次使用線程,所以我非常困惑,爲什麼Thread.CurrentThread.Name包含值null。我希望每個特定的線程都有一個自己的計時器,並且想要首先測試每個線程是否正在執行OnElapsed方法。然而,當我使用visual studio進行調試時,線程名似乎爲空。任何幫助,將不勝感激爲什麼線程名稱爲空?

public class Sample { 

    static System.Timers.Timer myTimer = new System.Timers.Timer(); 
    static int i = 0; 
    public static void Main() 
    { 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = @"C:\Users\Documents"; 

    watcher.NotifyFilter = NotifyFilters.LastWrite; 
    Thread.CurrentThread.Name = "main"; 

    watcher.Filter = "*.txt"; 

    watcher.Changed += new FileSystemEventHandler(OnChanged); 
    watcher.EnableRaisingEvents = true; 
    Console.WriteLine("Press the Enter key to exit the program."); 
    Console.ReadLine(); 

} 

private static void OnElapsed(object source, ElapsedEventArgs e) 
{ 
    Console.WriteLine(Thread.CurrentThread.Name); //<-- why is this null? 
    myTimer.Enabled = false; 
    Console.WriteLine(e.SignalTime); 
} 

private static void OnChanged(object source, FileSystemEventArgs e) 
{ 

     FileSystemWatcher t = source as FileSystemWatcher; 
     t.EnableRaisingEvents = false; 
     string path = e.FullPath;  
     Thread t1 = new Thread(() => Print(path)); 
     t1.Name = "Thread " + i; 
        i++; 
     t1.IsBackground = true; 
     t1.Start(); 
     t.EnableRaisingEvents = true; 

} 

static void Print(string source) 
{ 

      string xmlFilePath = "xmlBasic.xml"; 
      string timeout; 
      string path = Path.GetDirectoryName(source); 
      List<string> wordList = new List<string>(); 

      XmlDocument doc = new XmlDocument(); 
      doc.Load(xmlFilePath);   
      XmlNode timeouts; 
      XmlElement root = doc.DocumentElement; 
timeouts = root.SelectSingleNode("descendant::paths[directory='" + path + "']"); 

      timeout = timeouts.LastChild.InnerText; 
      myTimer.Interval = int.Parse(timeout); 
      myTimer.Elapsed += new ElapsedEventHandler(OnElapsed); 
      myTimer.Enabled = true; 

} 
} 

在此先感謝!

+5

我不知道很多關於這些事情,但我很好奇你期望它有什麼價值?正如我所看到的,你命名你的主線程,但事件觸發的任何線程將不會被命名爲任何明確的... – Chris

+0

因爲System.Timers.Timer會在另一個線程中引發(顯然是?)Elapsed事件。不在它創建的那個(你設置線程名稱的地方)。 –

回答

1

如果我們看一下,我們看到Timer.Elapsed Event documentation以下

如果物業對於SynchronizingObject爲null,經過的事件是 一個線程池線程提高。如果Elapsed事件 的處理持續時間超過間隔,則該事件可能會在另一個線程池線程上再次提升。在這種情況下,事件處理程序應該是 可重入。

這意味着引發事件的線程來自線程池,並且不會是您命名的線程。

如果你真的需要,使之成爲指定的線程,你必須創建例如實現ISynchronizeInvoke這裏的對象是一個由implementation喬恩斯基特

0

其空,因爲當FileSystemEventHandler處理OnElapsed事件時,它不在main的同一線程上運行。

如果您運行以下示例,您將看到Changed事件處理程序將運行在不同的線程中。

public static void Main(string[] args) 
{ 
    Directory.CreateDirectory("dir1"); 
    Directory.CreateDirectory("dir2"); 
    Directory.CreateDirectory("dir3"); 

    Console.WriteLine("Main Thread Id: {0}", 
     Thread.CurrentThread.ManagedThreadId); 

    const int watcherCount = 3; 
    string[] dirs = new string[] { "dir1", "dir2", "dir3" }; 

    for (int i = 0; i < watcherCount; i++) 
    { 
     var watcher = new FileSystemWatcher(); 
     watcher.Path = dirs[i]; 
     watcher.Changed += (sender, e) => 
     { 
      Console.WriteLine("File: {0} | Thread: {1}", e.Name, 
       Thread.CurrentThread.ManagedThreadId); 

      Thread.Sleep(2000); // Simulate long operation 
     }; 
     watcher.EnableRaisingEvents = true; 
    } 

    File.WriteAllText(@"dir1\test1", "hello"); 
    File.WriteAllText(@"dir2\test2", "hello"); 
    File.WriteAllText(@"dir3\test3", "hello"); 

    Thread.Sleep(10000); 
} 
相關問題