在单独的线程中填充 WPF 树视图



感谢您对以下问题的建议:我需要我的桌面 WPF 应用运行两个单独的线程:第一个线程:扫描目录中的文件。第二个线程:从第一个线程接收 FileInfo 对象,并将其作为新的 TreeViewItem 放入树视图控件中。我正在尝试使用Monitor静态方法解决此问题。

    public partial class MainWindow : Window
{
    private Thread scanThread, treeThread;
    public FileInfo scannedFile;
public object _lock = new object();
    public MainWindow()
    {
    InitializeComponent();
        scanThread = new Thread(new ParameterizedThreadStart(Scan));
        treeThread = new Thread(new ThreadStart(PopulateTree));
}
    private void Button_Click(object sender, RoutedEventArgs e)
{
            DirectoryInfo directory = new DirectoryInfo(FolderPath.Text); //I get FolderPath from FolderBrowserDialog
            scanThread.Start(directory);
            treeThread.Start();
}
    public void Scan(object dir)
    {
        DirectoryInfo _directory = (DirectoryInfo)dir;
        foreach (var file in _directory.GetFiles())
        {
            lock (_lock)
            {
                scannedFile = file;
                Monitor.Pulse(_lock);
                Monitor.Wait(_lock);
            }
        }
    }
public void PopulateTree()
    {
        this.Dispatcher.Invoke(() =>
        {
            if (scannedFile== null)
                return;
            lock (_lock)
            {
                var dirNode = new TreeViewItem();
                dirNode.Items.Add(scannedFile.Name);
                dirNode.Header = scannedFile.Name;
                MyTreeView.Items.Add(dirNode);
                Monitor.Pulse(_lock);
                Monitor.Wait(_lock);
            }
        });
    }

最终我得到了随机的奇怪结果 - 要么根本没有树视图填充,要么只有文件夹中的最后一个文件被添加到树视图中。也许是我无法正常工作的Monitor逻辑,或者我不应该使用公共扫描文件变量并以另一种方式将每个var file in _directory.GetFiles()传递给第二个线程?提前谢谢你!更新 我仅限于一些基本技术,例如监视器/等待句柄,因此必须在这些技术的范围内制定解决方案。

如果您使用的是WPF,我建议您采用MVVM模式。 应避免在窗口中使用代码隐藏,而应让 WPF 负责监视/线程逻辑。 为此,您应该创建文件/目录对象的模型(可能使用父类 FileSystemObject 或类似的东西(。 然后,您将在视图模型中具有某种可用于在视图中渲染的ObservableCollection<FileSystemObject>,该将包含您的TreeView。 通知示例代码的 WPF TreeView 可观察集合有一个很好的示例,用于执行类似于可用作起点的操作。

最新更新