2009-10-18 28 views
14

Kế hoạch của tôi là yêu cầu người dùng viết tiêu đề phim trong chương trình của tôi và chương trình của tôi sẽ kéo thông tin appropiate không đồng bộ để giao diện người dùng không bị đóng băng.Cách sử dụng phương thức WebClient.DownloadDataAsync() trong ngữ cảnh này?

Dưới đây là các mã:

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; 
     } 

vấn đề thực tế của tôi nằm trong phương pháp WebClientX.DownloadDataAsync(). Tôi không thể sử dụng URL chuỗi cho nó. Làm thế nào tôi có thể sử dụng được xây dựng trong chức năng để tải về các byte của trang web (để sử dụng sau này tôi sẽ chuyển đổi này thành chuỗi, tôi biết làm thế nào để làm điều này) và không có đóng băng lên GUI của tôi?

Có lẽ một ví dụ cắt rõ ràng của DownloadDataAsync để tôi có thể tìm hiểu cách sử dụng?

Cảm ơn SO, bạn luôn là một nguồn tài nguyên tuyệt vời.

+3

Re IMDB: Trang ngữ: "Robot và màn hình scraping: Bạn có thể không sử dụng khai thác dữ liệu, rô bốt, sàng lọc màn hình hoặc các công cụ thu thập và trích xuất dữ liệu tương tự trên trang web này, ngoại trừ với sự đồng ý bằng văn bản của chúng tôi như được nêu bên dưới ". Tôi ** đề nghị ** rằng bạn đừng ** không ** điều này; nó rõ ràng là chống lại các quy tắc của họ. –

+1

Marc, trang nào khác có thông tin như IMDB mà tôi CÓ THỂ sử dụng? Cảm ơn đã giúp đỡ. –

+0

Tôi thực sự không có ý tưởng. –

Trả lời

27

Bạn cần để xử lý các sự kiện 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"); 
} 

Các args chứa bit thông tin khác liên quan đến điều kiện lỗi vv - kiểm tra những người quá.

Cũng lưu ý rằng bạn sẽ tham gia vào DownloadDataCompleted trên một chuỗi khác; nếu bạn đang ở trong giao diện người dùng (winform, wpf, v.v.), bạn sẽ cần phải truy cập vào chuỗi giao diện người dùng trước khi cập nhật giao diện người dùng. Từ winforms, sử dụng this.Invoke. Đối với WPF, hãy xem Dispatcher.

+0

Chỉ để chấm-the-i, có một mẫu chuẩn để xử lý 'DownloadDataCompleted', như cho' RunWorkerCompleted', xem 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

Nếu bất kỳ ai sử dụng ở trên trong ứng dụng web hoặc trang web, vui lòng đặt Async = "true" trong khai báo chỉ thị trang trong tệp aspx.

20

Có phương thức DownloadDataTaskAsync mới hơn cho phép bạn đợi kết quả. Nó là đơn giản để đọc và dễ dàng hơn để dây lên cho đến nay. Tôi muốn sử dụng mà ...

var client = new WebClient(); 

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

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

Nhưng làm điều này là không giống nhau để thực hiện cuộc gọi một cách đồng bộ? (Đây là DownloadDataTask và trong trường hợp này bạn sẽ nhận được kết quả trực tiếp), nếu bạn muốn thực hiện cuộc gọi không đồng bộ, tôi nghĩ đây không phải là một tùy chọn, bởi vì nó hoạt động như đồng bộ. –

+0

Nó sử dụng async/await với lớp Task. Nó là không đồng bộ nhiều như câu trả lời ở trên là. Sự khác biệt duy nhất là bạn sử dụng một phương pháp tiếp tục DownloadDataCompleted ở trên và bạn sử dụng một await để inline sự tiếp tục trong phiên bản của tôi.Nếu bạn muốn báo cáo tiến độ hoặc giống như tôi có thể làm điều đó một cách khác nhau nhưng nếu bạn chỉ muốn tiếp tục hoàn thành theo cách này hoạt động cũng như với mã ít hơn. –

+1

Nếu bạn muốn làm những việc khác trong khi Nhiệm vụ đang chạy bạn chỉ không chờ đợi nó và làm công cụ của bạn, sau đó thêm một sự tiếp tục với nó. [Kiểm tra thông tin này] (https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/chaining-tasks-by-using-continuation-tasks). –

0

// sử dụng lớp ManualResetEvent

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); 
} 
Các vấn đề liên quan