2010-04-21 6 views
1

J'ai le code suivant qui traite un fichier binaire. Je veux diviser la charge de travail de traitement en utilisant des threads et en assignant chaque ligne du fichier binaire aux threads dans le ThreadPool. Le temps de traitement pour chaque ligne est limité, mais lorsqu'il s'agit de fichiers pouvant contenir des centaines de lignes, il est judicieux de diviser la charge de travail.Fichier binaire de processus C#, traitement multi-thread

Ma question concerne le BinaryReader et la sécurité des threads. Tout d'abord, est ce que je fais ci-dessous acceptable. J'ai le sentiment qu'il vaudrait mieux ne passer que le binaire de chaque ligne à la méthode PROCESS_Binary_Return_lineData.

Veuillez noter que le code ci-dessous est conceptuel. Je suis à la recherche d'un guide, mais mes connaissances en matière de multi-threading n'en sont qu'à leurs balbutiements. Il existe peut-être un meilleur moyen d'obtenir le même résultat, c'est-à-dire de diviser le traitement de chaque ligne binaire.

 var dic = new Dictionary<DateTime, Data>();   
     var resetEvent = new ManualResetEvent(false); 

     using (var b = new BinaryReader(File.Open(Constants.dataFile, 
          FileMode.Open, FileAccess.Read, FileShare.Read))) 
     { 
     var lByte = b.BaseStream.Length; 
     var toProcess = 0; 

     while (lByte >= DATALENGTH) 
     { 
      b.BaseStream.Position = lByte; 
      lByte = lByte - AB_DATALENGTH; 

      ThreadPool.QueueUserWorkItem(delegate 
      { 
       Interlocked.Increment(ref toProcess); 
       var lineData = PROCESS_Binary_Return_lineData(b); 

       lock(dic) 
       { 
        if (!dic.ContainsKey(lineData.DateTime)) 
        { 
        dic.Add(lineData.DateTime, lineData); 
        } 
       } 

       if (Interlocked.Decrement(ref toProcess) == 0) resetEvent.Set(); 
      }, null); 
     } 
     } 

     resetEvent.WaitOne(); 

Répondre

0

« Je sens que ce serait mieux passer que le binaire pour chaque ligne la méthode PROCESS_Binary_Return_lineData . »

oui, vous devez le faire, puisque votre délégué ne peut contourner à la lecture de la BinaryReader, avant qu'il ne soit repositionné

3

Cela ne me regarde pas thread-safe à. Si vous avez plus d'un élément de travail en file d'attente et que deux d'entre eux sont exécutés en même temps, la position du lecteur peut facilement changer entre l'affectation et la lecture.

Si vous insistez sur l'utilisation de threads pour cela, vous feriez mieux de lire les données dans votre thread principal et de mettre en file d'attente les tableaux d'octets qui en résultent pour la lecture. Toute solution impliquant la lecture de chaque thread à partir du fichier impliquera le verrouillage, et à ce stade, vous ne gagnez rien du tout à l'aide de threads.

+0

serait-ce des tableaux d'octets dérivés de: - var LineBytes = b.ReadBytes (DATALENGTH); ou devrais-je cloner les données dans un tableau d'octets pour m'assurer qu'il ne fait plus référence au flux de fichiers. – washtik

+0

Vous devriez simplement pouvoir utiliser le résultat de b.ReadBytes (DATALENGTH). – cHao

2

Il est très rarement judicieux d'utiliser des threads pour améliorer les performances de traitement de fichiers. Un thread, lorsqu'il est exécuté sur un processeur multi-core, fournit plus de cycles CPU. C'est rarement la ressource dont vous manquez lors du traitement des fichiers. Vous avez besoin de plus de disques. Pas une option bien sûr.

Test de fumée en premier. Redémarrez votre ordinateur pour que le fichier ne soit pas stocké dans le cache du système de fichiers. Exécutez votre programme monothread et observez la charge du processeur. Taskmgr.exe, onglet Performance est bon pour ça. Si vous ne voyez pas un processeur maximum à 100% de charge, l'ajout d'un autre processeur ne rendra pas votre programme plus rapide.