【问题标题】:Why is this method locking up my WPF UI?为什么这种方法会锁定我的 WPF UI?
【发布时间】:2016-07-15 08:00:05
【问题描述】:

我正在运行一个递归方法,它使用调度程序和并行处理来读取音乐元数据。我很困惑为什么它会锁定 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);
            }));

        }
    }));

}

【问题讨论】:

    标签: c# multithreading recursion parallel-processing


    【解决方案1】:

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

    无论您如何启动它,它都会被(实际上是多余的)回调到 UI 线程中。

    Application.Current.Dispatcher.BeginInvoke(

    就在第一行。

    据我所知,除了将项目添加到播放列表中之外,不需要任何这些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多