【问题标题】:FileSystemWatcher and GUIFileSystemWatcher 和 GUI
【发布时间】:2015-08-03 09:02:30
【问题描述】:

我的 WPF 项目和 FileSystemWatcher 类有一点问题。 在我的 MainWindow 类中,当在 UI 中单击“开始”按钮时,观察者开始观察文件夹。 一切正常,没有任何问题 - 观察者在创建文件时正确识别。 但是当观察者等待时,用户不可能在 UI 中做任何事情。例如应该可以点击停止...

 private void Start_Click(object sender, RoutedEventArgs e)
    {
        rdbTextBox.Document.Blocks.Clear();
        Start.IsEnabled = false;
        rdbTextBox.Document.Blocks.Add(new Paragraph(new Run("Test gestarte-Warte auf Befund....")));
        Stop.IsEnabled = true;

        watcher = new FileSystemWatcher(ConfigSettings.Default.FilePath); 

        // Only watch text files.
        // watcher.Filter = "*.bef";
        watcher.Filter = "*.txt";
        // Add event handlers.          
        watcher.Created += OnCreated;
        // Begin watching.
        watcher.EnableRaisingEvents = true;

        // Wait until new file in folder
        watcher.WaitForChanged(System.IO.WatcherChangeTypes.Created);           
        watcher.Dispose();

        // Parse letter
        edifactLetter = parser.ParseDocument(ConfigSettings.Default.FilePath + "\\" + fileName);
        // Validate Letter
        edifactVal.Validate(edifactLetter);

        writeResults();
        Start.IsEnabled = true;           
    }

    private void OnCreated(object sender, FileSystemEventArgs e)
    {   
        FileInfo file = new FileInfo(e.FullPath);
        fileName = file.Name;
    }

谁能解释我做错了什么? 谢谢!

【问题讨论】:

  • 顺便说一句:parseDocumentvalidate 的方法不是传统的 - 它们应该是 ParseDocumentValidate

标签: c# wpf filesystemwatcher


【解决方案1】:

这是因为WaitForChanged() 不是异步方法,它是同步的。这意味着如果您在 UI 线程中使用它,它将被阻止。

请看这里:https://msdn.microsoft.com/en-us/library/67220zhk(v=vs.110).aspx

我建议您可以为OnChanged 事件创建一个事件处理程序,然后执行您需要执行的操作。

【讨论】:

    【解决方案2】:

    是的,WaitForChanged 是同步方法:

    此方法无限期地等待,直到第一次更改发生,然后返回。

    您从 UI 线程调用它 - 因此在此期间阻止任何其他 UI 线程交互。你不想那样做。

    您可能应该只监听适当的事件 - 在事件处理程序中调用您的解析/验证方法。您还应该确保您在 UI 线程中完成所有 UI 工作,但理想情况下,other 工作尽可能少……所以除非解析和验证需要与 UI 交互,否则请在不同的线程。

    【讨论】:

    • 快速响应
    【解决方案3】:

    您可以标记方法async 并将长时间运行的任务放入任务中。不要忘记在第一个调用运行时阻止另一个调用:

    private async void Start_Click(object sender, RoutedEventArgs e)
    {
        var button = (Button)sender;
        button.Enabled = false;
        await Task.Run(() =>
        {
            .. long running task here will not block UI
        });
        button.Enabled = true;
    }
    

    【讨论】:

    • 拒绝投票,是的,我知道这不是专门处理文件监视程序的正确方法(因为它可能永远不会触发,因此永远停止),但它是一个不阻塞 UI 的任务的一般想法将在某个时候完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多