文件系统监视器和GUI

本文关键字:GUI 监视器 文件系统 | 更新日期: 2023-09-27 18:05:58

我的WPF项目和FileSystemWatcher类有一个小问题。在我的MainWindow类中,当在UI中单击按钮开始时,监视器开始监视文件夹。一切工作没有任何问题-监视器识别正确,当一个文件被创建。但是当观察者等待时,用户不可能在UI中做任何事情。例如,应该可以单击Stop…

 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;
    }
谁能告诉我我做错了什么?谢谢!

文件系统监视器和GUI

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

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

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

是,WaitForChanged是一个同步方法:

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

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

您可能应该只监听适当的事件—在事件处理程序中调用解析/验证方法。你还应该确保在UI线程中完成所有的UI工作,但理想情况下,其他的工作越少越好。因此,除非解析和验证需要与UI交互,否则请在另一个线程中进行。

可以标记方法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;
}