为什么这个方法会锁定我的WPF UI?

时间:2016-03-28 04:20:02

标签: c# multithreading recursion parallel-processing

我正在运行一个递归方法,它使用调度程序和并行处理来读取音乐元数据。我很困惑为什么它会锁定UI。我是否在新线程上启动方法并不重要。

它会长时间锁定UI,然后会更新,锁定等等。我很欣赏有关如何防止这种情况的一些意见。到目前为止,我已经使递归使用较低的优先级(背景)。因此,该方法以普通优先级运行,当它到达每个目录时,它以后台优先级调用自身(意味着在正常优先级线程完成之前它不会调用该递归。)

编辑:该方法实际上适用于较少数量的文件(小于1,000),但对于较大的目录(向上有超过50,000个音乐文件,它会显示此行为。)内存和CPU强度看起来很好。它不会耗尽内存,并且CPU使用率正常。

这个方法可以像:

一样调用
DirSearch("C:\MyMusicFolder\");

以下是方法:

private void DirSearch(string sDir)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
    {
        foreach (string path in Directory.GetDirectories(sDir))
        {
            Parallel.ForEach(Directory.EnumerateFiles(path, "*.mp3"), new ParallelOptions { MaxDegreeOfParallelism = 2 }, filename =>
            {

                try
                {
                   // filelist.Add(filename);

                    using (var mp3 = new Mp3File(filename))
                    {
                        Id3Tag tag = mp3.GetTag(Id3TagFamily.Version1x);
                        if (tag != null)
                        {
                            var listitem = new ArtistListItem();
                            listitem.Track = tag.Title;
                            listitem.Artist = tag.Artists;
                            listitem.Album = tag.Album;

                            Application.Current.Dispatcher.BeginInvoke(
                              DispatcherPriority.ContextIdle,
                              new Action(() => this.playlist.Items.Add(listitem)));
                        }
                    }
                }
                catch (Exception)
                {
                }

            });
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
            {
                DirSearch(path);
            }));

        }
    }));

}

1 个答案:

答案 0 :(得分:3)

它会阻止UI线程,因为它不会发生在另一个线程上。

无论你如何开始它,它都会被(通常是冗余的)调用混乱回到UI线程中。

  

Application.Current.Dispatcher.BeginInvoke(

就在第一行。

根据我的意见,除了将播放列表添加到播放列表之外,不需要任何其他内容。