有一个列表。
我想通过 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无论如何每次迭代。
