感谢您对以下问题的建议:我需要我的桌面 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 可观察集合有一个很好的示例,用于执行类似于可用作起点的操作。