2009-10-18 2 views
14

私の計画では、ユーザーが自分のプログラムにムービータイトルを書き留めて、プログラムが適切な情報を非同期的に取得してUIがフリーズしないようにします。このコンテキストでWebClient.DownloadDataAsync()メソッドを使用する方法?

は、ここでは、コードです:

public class IMDB 
    { 
     WebClient WebClientX = new WebClient(); 
     byte[] Buffer = null; 


     public string[] SearchForMovie(string SearchParameter) 
     { 
      //Format the search parameter so it forms a valid IMDB *SEARCH* url. 
      //From within the search website we're going to pull the actual movie 
      //link. 
      string sitesearchURL = FindURL(SearchParameter); 

      //Have a method download asynchronously the ENTIRE source code of the 
      //IMDB *search* website. 
      Buffer = WebClientX.DownloadDataAsync(sitesearchURL); 


      //Pass the IMDB source code to method findInformation(). 

      //string [] lol = findInformation(); 

      //???? 

      //Profit. 

      string[] lol = null; 
      return lol; 
     } 

私の実際の問題はWebClientX.DownloadDataAsync()メソッドです。私はそれのための文字列URLを使用することはできません。そのビルドイン関数を使用してサイトのバイトをダウンロードするにはどうすればよいですか(後で使用するためにこれを文字列に変換します、私はこれを行う方法を知っています)。

おそらく、私はそれを使用する方法を学ぶことができますDownloadDataAsyncの明確な例をカット?

ありがとう、あなたはいつもそんなに素晴らしいリソースです。

+3

再IMDB ManualResetEventクラスを使用して:利用規約のページ:「ロボットと画面スクレイピングは:あなたが使用することはできません。データマイニング、ロボット、スクリーンスクレイピング、または類似のデータ収集/抽出ツールを使用することはできません。私は**あなたがそうしていることを強くお勧めします**この**ではありません。それは明らかに彼らの規則に違反している。 –

+1

Marc、他のどのサイトにIMDBのような情報がありますか?助けてくれてありがとう。 –

+0

私はまったく考えていません。 –

答えて

27

あなたがDownloadDataCompletedイベントを処理する必要があります。

static void Main() 
{ 
    string url = "http://google.com"; 
    WebClient client = new WebClient(); 
    client.DownloadDataCompleted += DownloadDataCompleted; 
    client.DownloadDataAsync(new Uri(url)); 
    Console.ReadLine(); 
} 

static void DownloadDataCompleted(object sender, 
    DownloadDataCompletedEventArgs e) 
{ 
    byte[] raw = e.Result; 
    Console.WriteLine(raw.Length + " bytes received"); 
} 

引数は、などのエラー条件に関連する情報の他のビットが含まれています - あまりにもそれらを確認してください。

DownloadDataCompletedに別のスレッドで参加することにも注意してください。 UI(winform、wpfなど)にいる場合は、UIを更新する前にUIスレッドにアクセスする必要があります。 winformsからは、this.Invokeを使用します。 WPFについてはDispatcherをご覧ください。

+0

dot-the-iには、 'RunWorkerCompleted'のように' DownloadDataCompleted'を扱う標準パターンがあります。http://msdn.microsoft.com/en-us/library/cc221403%28VS.95を参照してください。 %29.aspx –

2
static void Main(string[] args) 
{ 
    byte[] data = null; 
    WebClient client = new WebClient(); 
    client.DownloadDataCompleted += 
     delegate(object sender, DownloadDataCompletedEventArgs e) 
     { 
      data = e.Result; 
     }; 
    Console.WriteLine("starting..."); 
    client.DownloadDataAsync(new Uri("http://stackoverflow.com/questions/")); 
    while (client.IsBusy) 
    { 
     Console.WriteLine("\twaiting..."); 
     Thread.Sleep(100); 
    } 
    Console.WriteLine("done. {0} bytes received;", data.Length); 
} 
2

WebアプリケーションやWebサイトで使用して上記の誰もがのaspxファイル内のpageディレクティブの宣言で=「true」を非同期に設定してください場合。

20

新しいDownloadDataTaskAsyncメソッドがあり、結果を待つことができます。読みやすく、ワイヤリングが簡単です。私はそれを使用したい...

var client = new WebClient(); 

var data = await client.DownloadDataTaskAsync(new Uri(imageUrl)); 

await outstream.WriteAsync(data, 0, data.Length); 
+0

しかしこれは同期方法で呼び出しを行うのと同じではありませんか? (これはDownloadDataTaskであり、この場合は結果を直接受け取ります)、非同期呼び出しを行う場合は、同期のように機能しているので、これはオプションではないと思います。 –

+0

タスククラスでasync/awaitを使用します。上記の答えと同じくらい非同期です。唯一の違いは、上記のContinuationメソッドDownloadDataCompletedを使用し、私のバージョンで継続をインライン化することを待つことです。進捗報告などが必要な場合は、私はそれを別々に行うかもしれませんが、完了の継続を望むだけであれば、このようにしてもコードは少なくて済みます。 –

+1

タスクが実行されている間に他のことをしたいのであれば、それを待っておらず、あなたのものをやり直してから、続けてください。 [情報を確認してください](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/chaining-tasks-by-using-continuation-tasks) –

0

//

static ManualResetEvent evnts = new ManualResetEvent(false); 
static void Main(string[] args) 
{ 
    byte[] data = null; 
    WebClient client = new WebClient(); 
    client.DownloadDataCompleted += 
     delegate(object sender, DownloadDataCompletedEventArgs e) 
     { 
      data = e.Result; 
      evnts.Set(); 
     }; 
    Console.WriteLine("starting..."); 
    evnts.Reset(); 
    client.DownloadDataAsync(new Uri("http://stackoverflow.com/questions/")); 
    evnts.WaitOne(); // wait to download complete 

    Console.WriteLine("done. {0} bytes received;", data.Length); 
} 
関連する問題