在单独的线程

时间:2017-02-13 14:05:05

标签: c# multithreading monitor

我将非常感谢您对我的问题的建议: 我需要我的桌面WPF应用程序来运行两个单独的线程: 第一个线程:扫描目录中的文件。 第二个线程:从第一个线程接收FileInfo对象,并将其作为新的TreeViewItem放在treeview控件中。 我试图使用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);
            }
        });
    }

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

1 个答案:

答案 0 :(得分:3)

如果您使用WPF,我建议采用MVVM模式。您应该避免在窗口中使用代码隐藏,而是让WPF负责监视/线程逻辑。为此,您应该创建文件/目录对象的模型(可能是父类FileSystemObject或类似的东西)。然后,您可以在 ViewModel 中使用某种ObservableCollection<FileSystemObject>查看中进行呈现,其中包含您的TreeViewWPF TreeView ObservableCollection notifying sample code有一个很好的例子,可以做一些类似于你可以用作起点的东西。

相关问题