示例程序:监听某个文件夹上的文件系统事件,并在计时器事件触发时将文件系统事件信息打印到控制台。
class Program
{
public static string location = @"D:\TestEvents";
public static double interval = 15000;
public static System.Timers.Timer timer;
public static List<string> listOfChanges = new List<string>();
static void Main(string[] args)
{
StartWatch();
StartTimer();
Console.ReadLine();
}
private static void StartWatch()
{
FileSystemWatcher Watcher = new FileSystemWatcher();
Watcher.Path = location;
Watcher.Created += new FileSystemEventHandler(OnFileCreatedOrDeleted);
Watcher.Deleted += new FileSystemEventHandler(OnFileCreatedOrDeleted);
Watcher.EnableRaisingEvents = true;
}
static void OnFileCreatedOrDeleted(object sender, FileSystemEventArgs e)
{
listOfChanges.Add(String.Format("Change Type: {0}, Name: {1}, Time: {2}", e.ChangeType, e.Name, DateTime.Now));
}
private static void StartTimer()
{
timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerEpleased);
timer.Interval = interval;
timer.Start();
}
private static void OnTimerEpleased(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer event fired: " + DateTime.Now);
foreach (var item in listOfChanges)
{
Console.WriteLine(item);
}
Console.WriteLine();
listOfChanges.Clear();
timer.Interval = interval;
timer.Start();
}
}
访问相同的存储静态List<string> listOfChanges
是否安全来自两个事件处理程序?
我真的不明白事件的底层是如何运作的。它是否创建一些全局事件处理程序队列并一一运行所有事件处理程序,无论事件类型如何?或者它为每个事件处理程序类型创建不同的线程?
编辑:
我想最好的解决方案是使用 BlockingCollection
与 ConcurrentQueue
,所以应该是这样的:
public static BlockingCollection<string> listOfChanges = new BlockingCollection<string>();
static void OnFileCreatedOrDeleted(object sender, FileSystemEventArgs e)
{
listOfChanges.Add(String.Format("Change Type: {0}, Name: {1}, Time: {2}", e.ChangeType, e.Name, DateTime.Now));
}
private static void OnTimerEpleased(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer event fired: " + DateTime.Now);
while (listOfChanges.Count > 0)
{
string item;
bool b = listOfChanges.TryTake(out item);
if (b)
{
Console.WriteLine(item);
}
}
Console.WriteLine();
timer.Interval = interval;
timer.Start();
}
最佳答案
通用列表不是线程安全的。当遍历 listOfChanges 时(在 OnTimerEpleased 中),您可能会收到错误,并且新条目将向列表中添加条目(OnFileCreatedOrDeleted)。请参阅http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx 。要么同步对列表的访问,要么使用内置的线程安全集合:http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
关于C# 事件和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13739697/