这是我第一次使用线程,所以我真的很困惑为什么Thread.CurrentThread.Name
包含值null
。我希望每个特定的线程都有自己的计时器,并希望首先测试每个线程是否正在执行OnElapsed
方法。但是,当我使用Visual Studio调试它时,线程名称似乎是null
。任何帮助将不胜感激。
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;
}
}
提前致谢!
答案 0 :(得分:1)
如果我们查看Timer.Elapsed Event documentation,我们会看到以下内容
如果SynchronizingObject属性为null,则Elapsed事件为 在ThreadPool线程上引发。如果处理了Elapsed事件 持续时间超过Interval,事件可能会再次提升 ThreadPool线程。在这种情况下,事件处理程序应该是 折返。
这意味着引发事件的线程来自线程池,而不是您命名的线程。
如果你真的需要让它成为一个指定的线程,你将不得不创建一个实现ISynchronizeInvoke的对象,例如这里是Jon Skeet的implementation
答案 1 :(得分:0)
它为null因为当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);
}