Skip to main content
 首页 » 编程设计

c#之区分多个 webclient 结果

2024年02月01日28luoye11

有一个列表。

我想通过 webclient.DownloadStringAsync 下载每个 url

我遇到的问题是: 我怎么知道哪个 e.Result 对应于哪个 url?

public class ressource{ 
public string url { get; set; } 
public string result  { get; set; } 
} 
 
List<ressource> urlist = new List<ressource>(); 
urlist.Add(new ressource(){url="blabla", result=string.empty}); 
....etc 
 
var wc= new WebClient(); 
foreach(var item in urlist) 
{ 
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted); 
    wc.DownloadStringAsync(new Uri(item.url, UriKind.Absolute)); 
} 
 
 void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
 { 
 urlist[?].result = e.Result;  
 } 

我觉得完全卡住了。 感谢您的想法。

请您参考如下方法:

the problem I encounter is: how do I know which e.Result corresponds to what url ?

对此有多种不同的选择:

用户状态

您可以将第二个参数传递给DownloadStringAsync ,然后可以通过 DownloadStringCompletedEventArgs.UserState 获得.例如:

// In your loop.... 
var wc = new WebClient(); 
wc.DownloadStringAsync(new Uri(item.url, UriKind.Absolute), item); 
 
void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
{ 
    var item = (ressource) e.UserState; 
    item.result = e.Result; 
} 

多个网络客户端

您可以创建一个新的 WebClient对于循环的每次迭代,并为其附加一个不同的事件处理程序。 lambda 表达式在这里很有用:

// Note: this is broken in C# 3 and 4 due to the capture semantics of foreach. 
// It should be fine in C# 5 though. 
foreach(var item in urlist) 
{ 
    var wc = new WebClient(); 
    wc.DownloadStringCompleted += (sender, args) => item.result = args.Result; 
    wc.DownloadStringAsync(new Uri(item.url, UriKind.Absolute)); 
} 

DownloadStringTaskAsync

你可以 DownloadStringTaskAsync 相反,这样每次调用都会返回一个 Task<string> .您可以保留这些的集合 - urlist 中的每个元素一个。 - 并且知道哪个是哪个。

或者,您可以同步获取所有结果,但我怀疑您不想这样做。

附加信息

不幸的是,WebClient不支持多个并发连接,因此使用所有 上面的选项你应该创建一个新的 WebClient无论如何每次迭代。