2016-03-28 21 views
0

Müzik meta verilerini okumak için dağıtım programlarını ve paralel işlemeyi kullanan özyinelemeli bir yöntem çalıştırıyorum. UI'yi neden kilitlediğini kafam karıştı. Yöntemi yeni bir iş parçacığına başlatıp başlatmama önemli değil.Bu yöntem neden WPF UI'mi kilitliyor?

UI'yi uzun süre kilitler, sonra günceller, kilitlenir ve benzeri. Bunu nasıl önleyeceğimize dair bazı bilgilerden memnun olurum. Şu ana kadar özyineleme kullanımını daha düşük bir öncelik (arka plan) yaptım. Yani yöntem, normal öncelikli çalışır ve bunun arka plan öncelikli kendisini çağıran her dizin ulaştığında (normal öncelik ipler bitinceye kadar bu özyinelemeye çağrı olmaz Anlam.)

Düzenleme: yöntem aslında gayet iyi çalışıyor Daha az sayıda dosya için (1.000'den az), ancak daha büyük dizinler için (50.000'den fazla müzik dosyası ile bu davranışı gösterir.) Bellek ve işlemci yoğunluğu iyi görünüyor. Bellek tükendi ve cpu kullanımı normal. İşte yöntemidir

DirSearch("C:\MyMusicFolder\"); 

:

bu yöntem

gibi çağrılabilir başka bir iş parçacığı üzerinde olmaz

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); 
      })); 

     } 
    })); 

} 

cevap

3

engeller UI iş parçacığı çünkü.

Nasıl başlatacağınıza bakılmaksızın, (aslında yedekli) kullanıcı arabirimine geri çağrıyla dağınık.

Application.Current.Dispatcher.BeginInvoke (

ilk satırda hakkı vardır.

biri HARİÇ Bunlardan herhangi biriyle gerek çalma listesine öğeler eklemek Orada do Görebildiğim kadarıyla

İlgili konular