我认为主视图模型是定义 FileSystemWatcher 的正确位置。至于线程问题,这是简单的方法:
_watcher = new FileSystemWatcher(path);
_watcher.Created += (obj, e) =>
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
// Code to handle Created event
};
_watcher.Changed += (obj, e) =>
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
// Code to handle Changed event
};
_watcher.Renamed += (obj, e) =>
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
// Code to handle Renamed event
};
_watcher.Deleted += (obj, e) =>
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
// Code to handle Deleted event
};
// ...
_watcher.EnableRaisingEvents = true;
每个“要处理的代码”都将在 UI 线程中执行,因此它可以更新ObservableCollection
. 请注意,此代码中提供了 FileSystemEventArgs “e”。
如果您喜欢使用单独的事件处理程序方法,您可以从上面的代码中调用它们或使用这个方便的快捷方式:
var switchThread =
(FileSystemEventHandler handler) =>
(object obj, FileSystemEventArgs e) =>
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
handler(obj, e))
_watcher = new FileSystemWatcher(path);
_watcher.Created += switchThread(OnCreated);
_watcher.Changed += switchThread(OnChanged);
_watcher.Deleted += switchThread(OnDeleted);
_watcher.Renamed += switchThread(OnRenamed);
_watcher.EnableRaisingEvents = true;
其中OnCreated
、OnChanged
、OnDeleted
和OnRenamed
是具有正常签名的正常事件处理程序方法,例如:
void OnChanged(object sender, FileSystemEventArgs e)
{
// Code to handle Changed event
}
我个人更喜欢第一种方法,因为我不喜欢创建四个额外的单行方法。
请注意,您的视图模型将需要知道要回调哪个 Dispatcher。最简单的方法是从 DispatcherObject 派生您的视图模型,如上所述。另一种方法是视图模型的构造函数或注册 FileSystemWatcher 事件的方法将 Dispatcher.Current 的副本存储在本地字段或本地变量中,然后将其用于 .BeginInvoke 调用。
另请注意,如果您愿意,可以在视图代码隐藏而不是视图模型中使用完全相同的代码。