2010-03-15 3 views
1

J'ai déjà essayé cette méthode, voici l'itération en cours. Je pense que je viens de mettre en œuvre tout faux. Ce que j'essaye d'accomplir est de traiter ce résultat d'Asynch de telle manière que jusqu'à ce qu'il retourne ET que je finisse avec mon appel d'add-thumbnail, je ne demanderai pas un autre appel à imageProvider.BeginGetImage.Problèmes lors de l'exécution des opérations asynchrones en C# en utilisant Mutex

Pour clarifier, ma question est double. Pourquoi ce que je fais ne semble jamais s'arrêter à mon appel Mutex.WaitOne(), et quelle est la bonne façon de gérer ce scénario?

 /// <summary> 
     /// re-creates a list of thumbnails from a list of TreeElementViewModels (directories) 
     /// </summary> 
     /// <param name="list">the list of TreeElementViewModels to process</param> 
     public void BeginLayout(List<AiTreeElementViewModel> list) 
     { 
      // *removed code for canceling and cleanup from previous calls* 

      // Starts the processing of all folders in parallel. 
      Task.Factory.StartNew(() => 
       { 
        thumbnailRequests = Parallel.ForEach<AiTreeElementViewModel>(list, options, ProcessFolder); 
       }); 
     } 

     /// <summary> 
     /// Processes a folder for all of it's image paths and loads them from disk. 
     /// </summary> 
     /// <param name="element">the tree element to process</param> 
     private void ProcessFolder(AiTreeElementViewModel element) 
     { 
      try 
      { 
       var images = ImageCrawler.GetImagePaths(element.Path); 

       AsyncCallback callback = AddThumbnail; 

       foreach (var image in images) 
       { 
        Console.WriteLine("Attempting Enter"); 

        synchMutex.WaitOne();  

        Console.WriteLine("Entered"); 

        var result = imageProvider.BeginGetImage(callback, image); 
       } 
      } 
      catch (Exception exc) 
      { 
       Console.WriteLine(exc.ToString()); 
       // TODO: Do Something here. 
      } 
     } 

     /// <summary> 
     /// Adds a thumbnail to the Browser 
     /// </summary> 
     /// <param name="result">an async result used for retrieving state data from the load task.</param> 
     private void AddThumbnail(IAsyncResult result) 
     { 
      lock (Thumbnails) 
      { 
       try 
       { 
        Stream image = imageProvider.EndGetImage(result); 
        string filename = imageProvider.GetImageName(result); 
        string imagePath = imageProvider.GetImagePath(result); 
        var imageviewmodel = new AiImageThumbnailViewModel(image, filename, imagePath); 
        thumbnailHash[imagePath] = imageviewmodel; 
        HostInvoke(() => Thumbnails.Add(imageviewmodel)); 
        UpdateChildZoom(); 
        //synchMutex.ReleaseMutex(); 
        Console.WriteLine("Exited"); 
       } 
       catch (Exception exc) 
       { 
        Console.WriteLine(exc.ToString()); 
        // TODO: Do Something here. 
       } 
      } 
     } 

Répondre

2

Pour commencer,

vous créez une tâche à faire un Parallel.ForEach pour exécuter une méthode qui Invoque un délégué.

Trois niveaux de parallélisme où 1 serait suffisant.

Et si je lis bien, dans le délégué, vous voulez utiliser un Mutex pour exécuter une seule instance à la fois.

Pourriez-vous indiquer les actions que vous voulez réaliser en parallèle?

+0

* rires * ouais c'était le résultat de la boucherie. l'exécution est la suivante: appels UI Begin Layout, en appuyant sur la tâche, il revient. La tâche doit ensuite traiter les dossiers. Je ne suis pas sûr pourquoi est le Parallel.ForEach, un forEach simple suffirait. O_O doit avoir été un reste de moi qui a battu le code. Et c'est exact, une seule instance de AddThumbnail devrait exécuter sa section critique à la fois. – Firoso

Questions connexes