2012-05-01 1 views
0

WebからダウンロードするURLは約800です。私はクラスを持っています:HttpDownloader.cs HttpWebRequestクラスを使用して、HTMLページをダウンロードして取得します。その後、私はRegexによってページを読み上げます。BackgroundWorkerコンポーネントによって多くのページをダウンロードします。

私はBackgroundWorkerコンポーネントを使用したいですが、私はそれを行う方法がわかりませんすべてページ。ループ、またはそのようなものによって。

マイコード:

私はThreadPoolのの使用を試みたが、それは本当に問題をしました。私は4つのURLで試してみて、うまくいきませんでした。

 foreach (string link in MyListOfUrls) 
     { 
ThreadPool.QueueUserWorkItem((o) => { 

      HttpDownloader httpDownload = new HttpDownloader(link); 
      string htmlDoc = httpDownload.GetPage();//get the html of the page 
      HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
      DoPharsing();//my func for pharsing 
      Save();//save into dataBase 
    }); 
     } 

私はThreadPoolのを使用する場合、私は例外を取得私のFUNC内のデータベースとのDataTableへの接続に使用するので:

前の関数の評価 がタイムアウトしたため無効」機能の評価はあなたが継続しなければなりません。関数 を再度有効にするための実行。

DataTableからデータを取得できません。たぶん私はすべてをダウンロードする必要があり、その後にpharsingして保存しますか?

BackgroundWorkerコンポーネントによって非同期に変更する方法はありますか?

p.s. Async Tpcで私にアドバイスしてはいけません。なぜなら私はそれをダウンロードできなかったからです。

おかげ

+0

複数のダウンロードを同時に実行したい場合や、ダウンロードをGUIから切り離したい場合(非同期にする) (構文解析ではなく、構文解析しています) – digEmAll

+0

@digEmAll、私は同時に複数のダウンロードを行いたいと思います。 ** **すべての**ページをより迅速にダウンロードする。 –

+0

何を試しましたか?バックグラウンドワーカークラスのインターネット上には数多くのチュートリアルがあります。あなたはこれらのチュートリアルのどれをどれだけ取得しましたか、具体的にあなたは何をしていますか? BackgroundWorkerを使用してコードを投稿してください。 –

答えて

0

私はここで最終的に私の答え
を見つけた私のコードです:

static BackgroundWorker[] d=new BackgroundWorker[MyListOfUrls.Length]; 
    string html=new string[MyListOfUrls.Length] 

    static void Main(string[] args) 
    { 
    for (int i = 0; i < MyListOfUrls.Length; i++) 
    { 
     d[i]=new BackgroundWorker{WorkerReportsProgress=true}; 
     d[i].DoWork += new DoWorkEventHandler(worker2_DoWork); 
     d[i].ProgressChanged += new ProgressChangedEventHandler(Program_ProgressChanged); 
     d[i].RunWorkerAsync(i); 
     d[i].RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted); 
     Thread.Sleep(1000); 
    } 
    } 

    static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("End"); 
    } 

    static void Program_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var worker = (BackgroundWorker)sender; 
     worker.ReportProgress((int)e.Argument); 

     HttpDownloader httpDownload = new HttpDownloader(link); 
     html[(int)e.Argument] = httpDownload.GetPage(); 

     Thread.Sleep(500); 
    } 

より良いそれを行う方法を誰もが知っていれば、私は幸せになります。 Thaks、 Chani

1

それは全体のループ、またはループのちょうどダウンロードの一部、あなたがオフに分割したいかに依存します。明らかに、ループ全体をバックグラウンドにしたいのであれば、最も簡単な方法はThreadPoolを使うことです。

注:HTMLドキュメントを各関数に渡すように、解析と保存の機能を変更する必要があります。単にあなたがスレッドを作成している場所を切り替える同時に複数のリンクをダウンロードするに

ThreadPool.QueueUserWorkItem((o) => { 
    foreach (string link in MyListOfUrls) 
    { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
} 
}); 

または

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += (o, e) => { 
    foreach (string link in MyListOfUrls) 
    { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
} 
}; 
worker.RunWorkerCompleted += (o, e) => { 
    // Job completed 
} 
worker.RunWorkerAsync(); 

foreach (string link in MyListOfUrls) 
{ 
    ThreadPool.QueueUserWorkItem((o) => { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
    }); 
} 
ここよりも、スレッドプールユーザー

(ベター私が思っているバックグラウンドワーカーの百dを作成する)。

+0

'Parallel.ForEach'を実行することもできます。ここでの実装の問題は、クリーンなキャンセルをサポートしていないことです。ダウンロードが完了したとき、または接続がタイムアウトしたときに、スレッドが完全にダウンロードを終了するまで待つ必要があります。これを解決する唯一の方法は、ノンブロッキングのダウンロードメカニズムを使用することです。この場合、スレッドを自分でキューに入れる必要はありません。 –

+0

上記の2つの例とは何が違うのですか?同じ時間にページをダウンロードすると、非同期ダウンロードですか? –

+0

@Chanipoz:ここには3つの例があります。最初の2つはほぼ同じで、GUIがぶら下がってしまうので便利です。同時に複数の文書をダウンロードすることはありません。 3番目は複数のドキュメントを同時にダウンロードしますが、多くのスレッドプール作業項目をキューに入れることができます。私はそれが問題ではないことを「キューに入れる」ことから推測しており、同時に内部的に多くのタスクしか実行しません。 –

関連する問題