FileSystemWatcher和GUI

时间:2015-08-03 09:02:30

标签: c# wpf filesystemwatcher

我的WPF项目和FileSystemWatcher类有点问题。 在我的MainWindow类中,当在UI中单击Button Start时,观察者开始观看文件夹。 一切正常,没有任何问题 - 观察者在创建文件时能够正确识别。 但是当观察者等待时,用户无法在UI中执行任何操作。 nexample应该可以单击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;
    }

任何人都能解释一下我做错了什么吗? 谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

是的,WaitForChanged是一种同步方法:

  

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

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

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

答案 2 :(得分:-2)

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