1

新人注意。問題: コンボ ボックスに入力すると、ユーザーが選択を行います。次に、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");
        }
     }
4

2 に答える 2

1

FileSystemWatcher実装しますIDisposable。したがってDispose、インスタンスを破棄するために呼び出す必要があります。

詳細については、次を参照してください。

于 2013-02-11T19:42:16.487 に答える
0

わかりました。ウォッチャーをどこかに保存する必要があるようですね。パスをキーにした辞書などでしょうか? また、クラスが破棄された状態で現在開いているウォッチャーをIDisposable適切に呼び出すことができるように、これがすべて implement に含まれているクラスも必要です。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();
     }
 }
于 2013-02-12T20:19:21.990 に答える