2009-10-18 51 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()方法。我无法为它使用字符串网址。我如何使用内置函数来下载网站的字节(以备后用,我将它转换为字符串,我知道如何做到这一点),而不会冻结我的GUI?

也许是DownloadDataAsync的一个明确的例子,所以我可以学习如何使用它?

谢谢,所以你总是这么好的资源。

+3

重新IMDB:条款页面:“机器人和屏幕抓取:您可能无法使用数据挖掘,机器人,屏幕抓取或本网站上的类似数据收集和提取工具,除非我们明确书面同意,如下所述。“。我**强烈建议**,你做**不**;这显然违反了他们的规则。 – 2009-10-18 20:53:59

+1

Marc,还有哪些其他网站有我可以使用的IMDB等信息?谢谢您的帮助。 – 2009-10-18 21:22:17

+0

我真的不知道。 – 2009-10-18 21:34:44

回答

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

的ARGS包含有关错误条件等信息,其他位 - 检查这些了。

另请注意,您将在不同的线程上进入DownloadDataCompleted;如果您处于UI(winform,wpf等)中,则需要在更新UI之前进入UI线程。从winforms,使用this.Invoke。对于WPF,请看Dispatcher

+0

只是点我,有一个处理'DownloadDataCompleted'的标准模式,就像'RunWorkerCompleted'一样,参见http://msdn.microsoft.com/en-us/library/cc221403%28VS.95 %29.aspx – 2009-10-18 21:47:12

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应用程序或网站上面使用人在aspx文件的页指令申报请设置异步=“真”。

20

有一个较新的DownloadDataTaskAsync方法,允许您等待结果。阅读起来更简单,并且更容易连线。我使用...

var client = new WebClient(); 

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

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

但这样做是不是同一种方式进行调用? (这是DownloadDataTask,在这种情况下,你会直接收到结果),如果你想做一个异步调用,我认为这不是一个选项,因为它像sync一样工作。 – 2017-11-22 12:41:01

+0

它使用异步/等待与任务类。和上面的答案一样,它是异步的。唯一的区别是你在上面使用了一个继续方法DownloadDataCompleted,你可以使用await来内联我的版本中的延续。如果你想获得进展报告或类似的报道,我可能会以不同的方式进行报道,但如果你只是希望在完成时继续下去,这种方式就可以用更少的代码工作。 – 2017-11-23 23:19:32

+1

如果你想在任务运行的时候做其他的事情,你只是不等待它,做你的事情,然后添加一个延续。 [检查此信息](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/chaining-tasks-by-using-continuation-tasks)。 – 2017-11-23 23:25:06

0

//使用的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); 
} 
相关问题