2009-10-18 8 views
14

Planım, bir kullanıcının programımda bir film başlığı yazmasını sağlamak ve programım UI donmadığı için uygun olmayan bilgiyi eşzamansız olarak çekecektir.Bu bağlamda WebClient.DownloadDataAsync() yöntemi nasıl kullanılır?

İşte kod:

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

Benim asıl sorun WebClientX.DownloadDataAsync() yöntemi yatıyor. Bunun için bir dize URL kullanamıyorum. Sitenin baytlarını indirmek için bu yerleşik işlevi nasıl kullanabilirim (daha sonra kullanmak için bunu dizeye dönüştüreceğim, bunu nasıl yapacağımı biliyorum) ve GUI'imi dondurmadan mı?

Belki DownloadDataAsync ile ilgili net bir örnek vermek için nasıl kullanacağımı öğrenebilirim?

Teşekkürler, her zaman çok iyi bir kaynağısınız.

+3

Re IMDB ManualResetEvent sınıf kullanarak: terimleri sayfa: "Robotlar ve Ekran Kazıma: Sen kullanamazsınız aşağıda belirtilen açık yazılı rızamız dışında, bu sitede veri madenciliği, robotlar, ekran kazıma veya benzeri veri toplama ve çıkarma araçları. " ** ** bunu ** yapmamanızı ** tavsiye ederim; Kurallarına açıkça aykırıdır. –

+1

Marc, başka bir site IMDB gibi bilgileri kullanabilir miyim? Yardım için teşekkürler. –

+0

Gerçekten hiçbir fikrim yok. –

cevap

27

Sen DownloadDataCompleted olayı işlemek gerekir:

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

args vb hata koşullarına ilişkin diğer bilgi bitlerini içerir - onları da kontrol edin.

Ayrıca farklı bir iş parçacığı üzerinde DownloadDataCompleted içine gireceğinizi unutmayın; Bir kullanıcı arayüzünde (winform, wpf, vb) iseniz, kullanıcı arayüzünü güncellemeden önce UI iş parçacığına erişmeniz gerekir. Winform'lardan this.Invoke'u kullanın. WPF için Dispatcher'a bakın.

+0

Sadece nokta-the-i için, 'RunWorkerCompleted' gibi' DownloadDataCompleted' işlevini kullanmak için standart bir model var, bkz. 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 uygulaması veya web sitelerinden yukarıdaki kullanarak herkes aspx dosyasındaki sayfa yönergesi bildiriminde zaman uyumsuz = "true" koyun lütfen varsa.

20

Sonucu beklemenizi sağlayan daha yeni bir DownloadDataTaskAsync yöntemi var. Çok fazla kablo okumak ve daha kolay bir şekilde kablolamak daha kolaydır. Bunu kullanmayı tercih ediyorum ...

var client = new WebClient(); 

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

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

Ama bu çağrıyı senkronize şekilde yapmakla aynı şey değil mi? (Bu bir DownloadDataTask ve bu durumda doğrudan sonucu alırsınız), eğer bir async çağrı yapmak istiyorsanız bu bir seçenek değil, çünkü senkronizasyon gibi çalışıyor. –

+0

Görev sınıfı ile birlikte async/wait'i kullanır. Yukarıdaki cevap kadar asenkrondir. Tek fark, yukarıdaki DownloadDataCompleted bir devam yöntemi kullanmak ve benim sürümde devam etmek için bir beklemek kullanın.İlerleme raporları veya benzer şeyler yapmak istiyorsanız, bunu farklı yapabilirim, ancak tamamlanma sürecine devam etmek istiyorsanız, bu şekilde daha az kodla da işlersiniz. –

+1

Görev çalışırken başka şeyler yapmak isterseniz, sadece onu beklemeyin ve eşyalarınızı yapın, ardından bir devam ekleyin. [Bilgi için bunu kontrol edin] (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); 
}