2009-11-04 5 views
1

Je fais un projet en ftp, ce qui fera plusieurs téléchargements, et le processus que je fais est de compresser le fichier, puis crypter puis couper en plusieurs morceaux et l'envoyer au serveur j'assigner toutes ces choses à un thread.likewise un thread sera là pour chaque fichier que j'assigne.Problème Avec le fil

c'est le nouveau morceau de code et il n'a qu'une seule fonctionnalité la même erreur apparaît ici aussi s'il vous plaît aidez-moi à trouver ce qui est erroné ici

public partial class Form1 : Form 

{ ArrayList AscendingList = new ArrayList(); ListViewItem Litem = null; Thread MyThread = null; ThreadStart Starter = null;

public Form1() 
{ 
    InitializeComponent(); 
} 

private void btn_split_Click(object sender, EventArgs e) 
{ 
    foreach (ListViewItem litem in listView1.Items) 
    { 
     Starter = delegate { SplitFile(litem.Text,litem.SubItems[1].Text,int.Parse(litem.SubItems[2].Text)); }; 
     MyThread = new Thread(Starter); 
     MyThread.IsBackground = true; 
     MyThread.Start(); 
    } 
} 
public void SplitFile(string inputFile, string outputPrefix, int chunkSize) 
{ 
    int pointr = 0; 
    byte[] buffer = new byte[chunkSize]; 

    using (FileStream fs = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
     int index = 0; 
     pointr = fs.Read(buffer, 0, buffer.Length); 
     while (pointr != 0) 
     { 
      using (FileStream fso = new FileStream(outputPrefix + "\\" + index + ".log", FileMode.Create)) 
      { 
       AscendingList.Add(fso.Name); 
       fso.Write(buffer, 0, pointr); 
       pointr = fs.Read(buffer, 0, buffer.Length); 
      } 
      index++; 
     } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Litem = new ListViewItem(); 
    Litem.Text = "E:\\butterfly.mpg"; 
    Litem.SubItems.Add("H:\\karthik"); 
    Litem.SubItems.Add("102400"); 
    listView1.Items.Add(Litem); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    Litem = new ListViewItem(); 
    Litem.Text = "E:\\karthik.mpeg"; 
    Litem.SubItems.Add("H:\\karthik\\karthik"); 
    Litem.SubItems.Add("102400"); 
    listView1.Items.Add(Litem); 
} 

}

+2

Fixer la mise en forme s'il vous plaît. – Yogesh

+1

Pouvez-vous fournir le message d'exception et stacktrace s'il vous plaît. – Jehof

+0

Veuillez utiliser 'Path.Combine()' !!! – knoopx

Répondre

13

Ce code est un désordre; vous devriez probablement essayer de le nettoyer. Dans le processus, vous pouvez découvrir que votre bug est résolu par lui-même.

  • Vous avez plusieurs clauses de capture vides, ce qui est un gros drapeau rouge (le commentaire en utilisant block est une bien meilleure idée). Ceux-ci doivent tous être être enlevés; Il est très improbable que ce soit une bonne idée.
  • Vous avez une instruction thread.Sleep qui est probablement superflue - et si ce n'est pas, c'est un signe d'un bug de threading.
  • Vous devez séparer la fonctionnalité de base en méthodes auxiliaires. Cela augmente la lisibilité et donc le débogage de votre code - et fournit automatiquement une documentation sous la forme du nom de la méthode d'assistance privée. Par exemple, votre lecture d'un code B d'écriture peut être une méthode - vous avez dupliqué cette fonctionnalité à la fois dans SplitFile et Decompress.
  • Vous avez un tas d'instructions erronées .Read( qui supposent que read lit réellement le tampon complet - il ne le fait pas, il attend qu'au moins 1 octet est disponible et retourne juste ce qui est immédiatement disponible, ou retourne 0 si le flux est fini . Vous devez jamais ignorer le nombre d'octets renvoyés par la méthode .Read(. Si vous séparez le (meilleur) code basé sur le temps de SplitFile et Decompress en une méthode d'assistance, vous pouvez également l'utiliser ailleurs. Ceci est susceptible de causer des problèmes lors de l'écriture sur un réseau ou un disque physique.
  • Plusieurs blocs utilisant peuvent être écrits sans accolades supplémentaires pour améliorer la lisibilité. Si vous faites cela, VS.NET n'ajoutera pas un niveau d'indentation pour chaque clause using(), mais seulement un pour chacun d'entre eux.
  • Ce n'est pas très clair pour moi, mais on dirait que vous travaillez avec un tas de fichiers intermédiaires.Une approche plus propre (et potentiellement beaucoup plus rapide) serait simplement de travailler sur les flux et d'avoir un wrapper qui fournit des flux de fichiers.
  • Vous n'avez pas besoin de .Flush() avant .Close().
  • Il est une bonne habitude de mettre vraiment chaqueIDisposable dans un bloc à l'aide. Même les choses comme MemoryStream et CryptoStream - il est probablement pas à la matière, mais je vois que vous .Close() les -ment de toute façon (vous n'êtes pas économiser de code), et vous ne respecte pas le code contrat et vous n'avez probablement pas connaître leur mise en œuvre, donc vous comptez sur un comportement non spécifié; ça ne vaut pas le coup.
  • .Substring(....).ToString() est équivalent à .Substring()

Fondamentalement, il semble que vous faites une grande chose compliquée en utilisant la technologie que vous n'êtes pas tout à fait au courant; essayez de le diviser en petits morceaux propres qui vous permettent de déterminer plus précisément ce dont vous avez besoin - de cette façon, vous pouvez mieux garder le contrôle de toute nouvelle technologie.

Nettoyez ce que vous avez en premier; essayez repérer une erreur qui (s) il vous reste - si vous êtes un peu de chance, vous n'aurez pas ...

J'espère que cela aide!

1

Pourquoi utilisez-vous FileShare.ReadWrite lors de la création fsout, vous essayez d'écrire dans le même fichier à partir de fils différents? Cela ne fonctionnera pas, du moins pas en utilisant GZipStream comme ça. Avec l'autre fichier que vous écrivez, vous avez spécifié FileShare.None, ce qui, je suppose, signifie que vous n'essayez pas d'écrire dans le même fichier à partir de plusieurs threads dans ce cas.

+0

salut maxc je dnt essayer d'écrire dans un même fichier à partir de différents threads, j'ai chnaged le gzipstream aussi, mais un de mes thread est arrêté en disant incapable d'accéder à un fichier.the passe, qu'il soit est une condition de course – karthik

2

Cela pose problème:

string EncryptedFile = ""; 
Slicer.SplitFile(EncryptedFile, lt.SubItems[3].Text, 10240); 

L'appel Slicer.SplitFile() est invité à travailler sur un fichier inexistant.

1

incapable d'accéder au fichier

Cette situation est commune pour les applications multithread où plusieurs threads tentent d'accéder au même fichier.

Ce que vous devez faire est de vous assurer que cela ne se produit pas.
Vous ne devez pas partager d'objets et chaque thread doit fonctionner avec ses propres fichiers (pas d'intersectinos).

En regardant le code que je peux voir que Slicer. instace est partagée.
Essayez de déplacer tout le code dans délégué de démarrage du fil et instancier tous les objets là.

+0

Lire à partir du fichier en utilisant plusieurs threads est très bien. Si elle est soigneusement conçue, cette approche peut augmenter les performances. –

+0

Oui. Ce que je veux dire, c'est que ce n'est pas bien si elle n'est pas correctement mise en oeuvre. –

+0

Ceci est la bonne réponse, c'est la bonne raison de l'échec de mon code – karthik