hola a todos
ho un problemuccio ... ho sviluppato un piccolo software che funziona come un crawler web
il funzionamento è semplice ... io do una lista inziale, avvio N threads, ogni threads monitora la lista e quando è piena acquisisce la prima riga eliminandola, acquisisce i dati dal web aggiunge l'indirizzo letto ad una lista di indirizzi acquisiti e poi aggiunge gli indirizzi acquisiti validi di nuovo nella lista iniziale
il mio problema è che solo un thread per volta lavora :\
e la cosa la ritengo assurda!!!!!!!!!!!
ora siccome non so se è un errore mio a livello pratico o a livello logico (perché ovvimante è un'errore mio) volevo sapere se avevate avuto esperienze simili o comunque esperienze con l'accoppiata Threading e WebRequest
premetto che funziona, nel senso che fa tutto quello che deve fare correttamente a parte che lavora un thread per voltacodice:private void WebCrawlingThread() { Random randomNumberGenerator = new Random(234432); WebClient webClient = new WebClient(); Regex addressesRegex = new Regex("href=\"([^\"]+)\"", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline); Regex queryStringRegex = new Regex("([^&]+)&?", RegexOptions.Compiled | RegexOptions.IgnoreCase); string address = ""; System.Console.WriteLine("Thread <{0}> wait for all threads", Thread.CurrentThread.Name); System.Console.Out.Flush(); while(terminateThreads == false && threadsCanStart == false) { Application.DoEvents(); } System.Console.WriteLine("Thread <{0}> started", Thread.CurrentThread.Name); System.Console.Out.Flush(); while(true) { Application.DoEvents(); // Check if threads must exits if (terminateThreads == true) { break; } // Check if there are addresses in the address list Monitor.Enter(this.addressList); if (this.addressList.Count == 0) { Monitor.Exit(this.addressList); continue; } // Acquire the page address = (string)this.addressList[0]; this.addressList.RemoveAt(0); Monitor.Exit(this.addressList); try { Monitor.Enter(this.threadStatus); this.threadStatus[Thread.CurrentThread.Name] = address; // DOWNLOADING PAGE Monitor.Exit(this.threadStatus); // Download the page byte[] downloadedDataBytes = webClient.DownloadData(address); string downloadedDataString = System.Text.Encoding.ASCII.GetString(downloadedDataBytes); Monitor.Enter(this.downloadedDataSize); this.downloadedDataSize += (ulong)downloadedDataBytes.Length; Monitor.Exit(this.downloadedDataSize); // Check the page MatchCollection resultsAddresses = addressesRegex.Matches(downloadedDataString); ArrayList foundedAddresses = new ArrayList(); for(int currentMatch = 0; currentMatch < resultsAddresses.Count; currentMatch++) { string extractedAddress = resultsAddresses[currentMatch].Groups[1].Value.Replace("&", "&"); if ( foundedAddresses.Contains(extractedAddress) == false && crawledAddressList.Contains(extractedAddress) == false && extractedAddress.ToLower().StartsWith("http://") == true ) { int queryStringStartPosition = extractedAddress.IndexOf("?"); if (queryStringStartPosition > 0) { if (queryStringRegex.Matches(extractedAddress, queryStringStartPosition + 1).Count > 2) { continue; } } foundedAddresses.Add(extractedAddress); } } System.Console.WriteLine("Thread <{0}> downloaded data from {1} founded {2} links!", Thread.CurrentThread.Name, address, foundedAddresses.Count.ToString()); System.Console.Out.Flush(); // Add datas to the list Monitor.Enter(this.addressList); this.addressList.AddRange(foundedAddresses.ToArray()); Monitor.Exit(this.addressList); } catch(WebException e) { System.Console.WriteLine("Thread <{0}> exception, error type {1}!", Thread.CurrentThread.Name, e.Status.ToString()); System.Console.Out.Flush(); } // Update crawled addresses Monitor.Enter(this.crawledAddressList); this.crawledAddressList.Add(address); Monitor.Exit(this.crawledAddressList); Monitor.Enter(this.threadStatus); this.threadStatus[Thread.CurrentThread.Name] = ""; Monitor.Exit(this.threadStatus); System.Console.WriteLine("Thread <{0}> cycle done, readed {1}!", Thread.CurrentThread.Name, address); System.Console.Out.Flush(); } // Advise the user that the thread is aborted System.Console.WriteLine("Thread <{0}> aborting!", Thread.CurrentThread.Name); System.Console.Out.Flush(); // Terminate the thread Thread.CurrentThread.Abort(); }
il mio sospetto è che sia questa riga qui
quella che blocca tuttocodice:byte[] downloadedDataBytes = webClient.DownloadData(address);
(lasciate perdere errori o dimenticanze nel codice, molte cose sono volute perché mi interessava soltanto testare il funzionamento di una struttura di questo tipo in C# per vedere se funzionava bene o meno)
qualcuno ha qualche idea?

Rispondi quotando