Pętla równoległa i zdarzenia

0

Cześć, mam problem z pętlą równoległą i eventami. funkcja TraverseTree to przeszukiwanie iteracyjne katalogów. W pętli równoległej przeszukuje każdy dysk. Zdarzenia wykorzystuję do aktualizowania kontrolki z nazwami plików które zostały już znalezione. Niestety po bardzo krótkiej chwili zużycie CPU maleje do 0 i program zalicza dedlocka Gdy zastosuję zwykłego foreacha to nie ma problemu. jakieś wskazówki ?

List<string> drives = new List<string>() {@"E:\",  @"F:\", @"G:\",  @"i:\", @"D:\" };
Parallel.ForEach(drives, drive => TraverseTree(drive));
public  void TraverseTree(string root)
        {
            // struktura do przechowywania nazw folderów
            Stack<string> dirs = new Stack<string>(20);

            if (!System.IO.Directory.Exists(root))
            {
                return;
            }
            dirs.Push(root);

            while (dirs.Count > 0)
            {
                string currentDir = dirs.Pop();
                string[] subDirs;
                try
                {
                    subDirs = System.IO.Directory.GetDirectories(currentDir);
                }

                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }         
                try
                {
                    List<string> list = new List<string>();
                    foreach (var item in fileExtensions)
                    {
                        string[] files = System.IO.Directory.GetFiles(currentDir, item);
                        movieFileList.AddRange(files);
                        list.AddRange(files);                      
                        
                    }
                    onFilesFound(list.ToArray()); //// aktualizacja kontrolki z
                }

                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }

                foreach (string str in subDirs)
                    dirs.Push(str);
            }
        }

Event

  public delegate void FilesFoundEventHandler(object sender, FilesFoundEventArgs e);
        public event FilesFoundEventHandler FilesFound;
        protected void onFilesFound(string[] filesPaths)

        {

            if (FilesFound != null)
                   FilesFound(this, new FilesFoundEventArgs() { NewFilesPaths = filesPaths, NewFilesCount = filesPaths.Length });
                
            
        }
0

Niestety to nie rozwiązuje problemu

0

Pokaż jak zmodyfikowałeś kod używając Dispatchera. Bo raczej nie powinno być z tym problemu.

0
    Dispatcher dispatcherUI = Dispatcher.CurrentDispatcher;
        Action<string[]> action ;
        void  fileSearcher_FilesFound(object sender, LocalFilesSearcher.FilesFoundEventArgs e)
        {
            addMoviesFilePathsToList(e.NewFilesPaths);
            dispatcherUI.Invoke(action, new object[] { e.NewFilesPaths});
        }
 fileSearcher.FilesFound += fileSearcher_FilesFound;

Po zastosowaniu tego program kończy z sukcesem przeszukiwanie, ale znajduje tylko niewielką część plików

0

Mój błąd! Wszystko działa dzięki dispatcher

   Dispatcher dispatcherUI = Dispatcher.CurrentDispatcher;
        Action<string[]> action ;
        void  fileSearcher_FilesFound(object sender, LocalFilesSearcher.FilesFoundEventArgs e)
        {
           <u> addMoviesFilePathsToList(e.NewFilesPaths);</u>
            dispatcherUI.Invoke(action, new object[] { e.NewFilesPaths});
        }

Metoda addMoviesFilePathsToList wykonuje się w action i to ona zmienia kontrolkę, zapomniałem jej usunąć. Wszystko działa! Dziękuję za pomoc!

1 użytkowników online, w tym zalogowanych: 0, gości: 1