打开和关闭FileSystemWatcher以避免出现多个实例

本文关键字:实例 FileSystemWatcher | 更新日期: 2023-09-27 17:58:38

Newbee警报。问题:我填充了一个组合框,用户进行了选择。然后创建并启用FSW。所有操作都很好,直到用户重新访问组合框进行替换选择。此时,另一个FSW被实例化,导致基于"使用中的文件"错误的IO异常。当用户在组合框中进行后续选择时,我需要关闭FSW(或销毁实例化)。整个程序是从带有组合框的Winform驱动的。

当用户重新访问组合框并进行另一次选择时,如何打开/关闭FSW,或者销毁FSW实例化并允许创建一个新的、类似的实例?

调用FSW实例化的代码:

        private void MinAndGo()
    {
        if (strLblPtr != null)
        {
            if(strLblPtr != "None")
            {
                if (!CheckMyPrinter(strLblPtr))
                {
                    MessageBox.Show(ForegroundWindow.Instance, "Printer is not ready. Make sure it's turned on "
                    + "and has paper loaded.", "Printer Not Ready");
                }
            }
            this.WindowState = FormWindowState.Minimized;
            this.Activate();
            bCreateWatcher = true;
            Watchit();
        }
    }

WatchIt()的代码。我打算使用bool bCreateWatcher来打开和关闭FSW。

private static void Watchit()
    {
        List<string> list = new List<string>();
        list.Add("C:''SAMMS''pcl");
        list.Add("C:''SAMMS''lbl");
        foreach (string my_path in list)
        {
            Watch(my_path);
        }
    }
    private static void Watch(string watch_folder)
    {
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.InternalBufferSize = 8192; //defaults to 4KB, need 8KB buffer
        watcher.Path = watch_folder;
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        watcher.Filter = "*.*"; 
        watcher.Created += new FileSystemEventHandler(OnCreated);
        // Begin watching.
        try
        {
            if (bCreateWatcher)
            {
                watcher.EnableRaisingEvents = true;
            }
            else
            {
                watcher.EnableRaisingEvents = false;
            }
        }
        catch(Exception ex)
        {
            MessageBox.Show(ForegroundWindow.Instance, "FSW not set correctly" + ex, "FSW Error");
        }
     }

打开和关闭FileSystemWatcher以避免出现多个实例

FileSystemWatcher实现IDisposable。因此,您应该调用Dispose来销毁该实例。

您可以在这里找到更多信息:

  • http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.dispose(v=vs.80).aspx
  • http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

好吧,看起来你需要把你的观察程序存储在某个地方,也许是一个键入路径的字典?您还需要实现IDisposable中包含的类,这样您就可以在当前打开的任何观察程序上正确地调用Dispose()。该类已被处理。(然后,您应该确保包含类也被正确地处理。)

我会把Watch()重构成这样(可能会更好):

private static IDictionary<string, FileSystemWatcher> _openWatchers
    = new Dictionary<string, FileSystemWatcher>();
private static void Watch(string watch_folder)
{
    if (!bCreateWatcher)
    {
        if (_openWatchers.ContainsKey(watch_folder))
        {
            _openWatchers[watch_folder].Dispose();
            _openWatchers.Remove(watch_folder);
        }
        return;
    }
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.InternalBufferSize = 8192; //defaults to 4KB, need 8KB buffer
    watcher.Path = watch_folder;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
   | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.Filter = "*.*"; 
    watcher.Created += new FileSystemEventHandler(OnCreated);
    // Begin watching.
    try
    {
         watcher.EnableRaisingEvents = true;
         _openWatchers[watch_folder] = watcher;
    }
    catch(Exception ex)
    {
        MessageBox.Show(ForegroundWindow.Instance, "FSW not set correctly" + ex, "FSW Error");
    }
 }

以及您的Dispose()方法:

 public void Dispose()
 {
     foreach (FileSystemWatcher fsw in _openWatchers.Values)
     {
          fsw.Dispose();
     }
 }