2010-09-10 4 views
0

Je suis le programme de codage sur C# (C#, & newbie de programmation orientée objet) Je suis en train de télécharger des pages dans plusieurs threads. Il n'y a pas de problèmes lors de l'exécution de seulement 1 thread. Les problèmes commencent quand je cours plusieurs fois.Libcurl via les threads

Il semble que tous les threads enregistrer les informations téléchargées dans la même variable SockBuff, mais je n'ai aucune idée de ce qu'il faut faire pour résoudre ce problème.

Suggestions?

Voici le code

programme commence lorsque je clique sur le bouton.

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     void TestaThread_1() 
     { 
      Random RandomNumber = new Random(); 
      int rand = RandomNumber.Next(99); 

      HTTP cURL = new HTTP(); 
      cURL.CurlInit(); 
      String data = cURL.HTTPGet("http://google.com", "", "fails" + rand.ToString() + ".html"); 
      HTTP.save_file("fails" + rand.ToString()+ ".html", data); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Thread thread1 = new Thread(new ThreadStart(TestaThread_1)); 
      thread1.Start(); 

      Thread thread2 = new Thread(new ThreadStart(TestaThread_1)); 
      thread2.Start(); 

      Thread thread3 = new Thread(new ThreadStart(TestaThread_1)); 
      thread3.Start(); 

      Thread thread4 = new Thread(new ThreadStart(TestaThread_1)); 
      thread4.Start(); 

      Thread thread5 = new Thread(new ThreadStart(TestaThread_1)); 
      thread5.Start(); 
     } 
    } 

    class HTTP 
    { 
     public Easy easy;   
     public static string SockBuff; 
     public string CookieFile = AppDomain.CurrentDomain.BaseDirectory + "cookie.txt"; 
     public string UserAgent = "Mozilla 5.0"; 
     public string Proxy = ""; 


     public void CurlInit() 
     { 
      Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL); 
     } 


     public string HTTPGet(string URL, string Proxy, String FailaNosaukums) 
     { 
      easy = new Easy(); 
      SockBuff = ""; 

      try 
      { 
       Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData); 

       easy.SetOpt(CURLoption.CURLOPT_URL, URL); 
       easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, "60"); 
       easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf); 
       easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent); 
       easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile); 
       easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile); 
       easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true); 

       if (URL.Contains("https")) 
       { 
        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1); 
        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0); 
       } 

       if (Proxy != "") 
       { 
        easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy); 
        easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, CURLproxyType.CURLPROXY_HTTP); 
       } 

       easy.Perform(); 
       easy.Cleanup(); 

      } 
      catch 
      { 
       Console.WriteLine("Get Request Error"); 
      } 

      return SockBuff; 
     } 


     public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData) 
     { 
      Random rand = new Random(); 
      int RandomNumber = rand.Next(1000); 

      SockBuff = SockBuff + System.Text.Encoding.UTF8.GetString(buf); 

      return size * nmemb; 
     } 

     static public void save_file(string file_name, string text_to_write) 
     { 
      StreamWriter MyStream = null; 
      string MyString = text_to_write; 

      try 
      { 
       MyStream = File.CreateText(file_name); 
       MyStream.Write(MyString); 
      } 
      catch (IOException e) 
      { 
       Console.WriteLine(e); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e); 
      } 
      finally 
      { 
       if (MyStream != null) 
        MyStream.Close(); 
      } 
     } 
    } 
} 

j'ai eu une autre question. Pourquoi ne puis-je pas enregistrer les fichiers image en utilisant correctement la fonction save_file? Y a-t-il des problèmes d'encodage dans le buff?

Répondre

1

Le problème est que votre SockBuff est static, donc il n'y a qu'une seule instance de cette variable qui est partagée par toutes les instances de la classe HTTP. Vous pouvez probablement résoudre le problème en supprimant le static.

Si vous faites cela, vous devrez également faire de votre méthode OnWriteData une méthode d'instance (c'est-à-dire pas statique).

Vous pouvez également envisager d'utiliser les classes System.Net.WebClient et/ou System.Net.HttpWebRequest au lieu de Libcurl.

+0

Bien travaillé! Merci. Pourquoi le System.Net est-il meilleur que le libcurl? – user444434

+0

Je suis heureux ma réponse a été utile. Ce n'est pas que les classes System.Net sont 'meilleures' que Libcurl. Honnêtement, je ne connais pas assez Libcurl sur .NET pour dire lequel est le meilleur. Mais dans mon expérience, il est logique d'utiliser les bibliothèques .NET quand cela est possible car cela simplifie les choses (ne pas inclure d'autres bibliothèques), elles fonctionnent généralement bien, et elles seront plus largement utilisées et comprises (ce qui signifie que je peux obtenir facilement de l'aide si j'en ai besoin). –

+0

@ user444434 Pouvez-vous s'il vous plaît partager comment vous avez résolu ce qui précède avec des discussions? – confusedMind