C# 使用WebClient和TaskAsync从异步CTP下载的UserState
我目前正在使用异步CTP,需要将此代码转换为可以使用Task.WhenAll()的代码 到目前为止,我所做的是使用UserState对象并将我的标识符(AID)放入其中,然后在完成的事件中使用它 但是wc.DownloadFileTaskAsync方法没有UserState重载。我能做什么C# 使用WebClient和TaskAsync从异步CTP下载的UserState,c#,asynchronous,webclient,async-ctp,C#,Asynchronous,Webclient,Async Ctp,我目前正在使用异步CTP,需要将此代码转换为可以使用Task.WhenAll()的代码 到目前为止,我所做的是使用UserState对象并将我的标识符(AID)放入其中,然后在完成的事件中使用它 但是wc.DownloadFileTaskAsync方法没有UserState重载。我能做什么 for (int i = 0; i < SortedRecommendations.Count; i++) { string tempfilepath = filepath + SortedRe
for (int i = 0; i < SortedRecommendations.Count; i++)
{
string tempfilepath = filepath + SortedRecommendations[i].Aid + ".jpg";
if (File.Exists(tempfilepath))
continue;
WebClient wc = new WebClient();
wc.DownloadFileCompleted += (s, e) =>
{
var q = SortedRecommendations.Where(x => x.Aid == (int)e.UserState);
if (q.Count() > 0)
q.First().Image = tempfilepath;
};
wc.DownloadFileAsync(new Uri(SortedRecommendations[i].Image.Replace("t.jpg", ".jpg")), tempfilepath, SortedRecommendations[i].Aid);
}
for(int i=0;i
{
var q=分类推荐。其中(x=>x.Aid==(int)e.UserState);
如果(q.Count()>0)
q、 First().Image=tempfilepath;
};
wc.DownloadFileAsync(新Uri(sortedRecommensions[i].Image.Replace(“t.jpg”,“.jpg”))、tempfilepath、sortedRecommensions[i].Aid);
}
这基本上就是我想到的,但是我在y.Aid==SortedRecommendations[I].Aid处得到了一个ouf界限外的异常,因为我现在明显是下载开始时的其他东西。我看到的唯一其他可能性是使用类似TaskEx.Run(()=>{//同步下载数据})的东西;但我不喜欢这种方法
for (int i = 0; i < SortedRecommendations.Count; i++)
{
string tempfilepath = filepath + SortedRecommendations[i].Aid + ".jpg";
if (File.Exists(tempfilepath))
continue;
WebClient wc = new WebClient();
wc.DownloadFileCompleted += (s, e) =>
{
var q = SortedRecommendations.Where(x => x.Aid == SortedRecommendations[i].Aid);
if (q.Count() > 0)
q.First().Image = tempfilepath;
};
tasks.Add(wc.DownloadFileTaskAsync(new Uri(SortedRecommendations[i].Image.Replace("t.jpg", ".jpg")), tempfilepath));
}
await TaskEx.WhenAll(tasks);
//Everything finished
for(int i=0;i
{
var q=分类推荐。其中(x=>x.Aid==分类推荐[i].Aid);
如果(q.Count()>0)
q、 First().Image=tempfilepath;
};
tasks.Add(wc.downloadfiletasksync(新Uri(sortedRecommensions[i].Image.Replace(“t.jpg”,“.jpg”)),tempfilepath));
}
等待TaskEx.WhenAll(任务);
//一切都结束了
首先,我认为您不应该将逻辑基于ID(除非您真的必须这样做)。您应该使用对SortedRecommensions
集合中对象的引用
现在,如果您想一次只下载一个文件,只需使用wait
:
for (int i = 0; i < SortedRecommendations.Count; i++)
{
string tempfilepath = filepath + SortedRecommendations[i].Aid + ".jpg";
if (File.Exists(tempfilepath))
continue;
WebClient wc = new WebClient();
var recommendation = SortedRecommendations[i];
await wc.DownloadFileTaskAsync(new Uri(recommendation.Image.Replace("t.jpg", ".jpg")), tempfilepath);
recommendation.Image = tempfilepath;
}
最好的解决方案可能是一次下载有限数量的文件,而不是一个或全部文件。这样做更复杂,一个解决方案是使用TPL数据流中的
ActionBlock
,并设置MaxDegreeOfParallelism
。如果可以的话,应该使用VS2012 RC而不是CTP。它包含许多改进nts和错误修复。另外,您确定要同时开始下载所有文件吗?是的,我想同时下载所有文件(+好的,ctp使用线程池并选择适当数量的并行线程。)。我不能使用.NET 4.5,因为我依赖Blend。而Blend,即使是您使用VS12获得的,也不能与.NET 4.5正常工作。(通过艰难的途径发现了这一点…)它确实使用了线程池
(在正常情况下),但这只能为短时间的CPU绑定操作选择适当数量的线程。它根本不适用于异步IO操作,因为异步部分不使用任何线程。因此,您的所有文件将大约同时开始下载。谢谢!不知道ContinueWith。!
for (int i = 0; i < SortedRecommendations.Count; i++)
{
string tempfilepath = filepath + SortedRecommendations[i].Aid + ".jpg";
if (File.Exists(tempfilepath))
continue;
WebClient wc = new WebClient();
var recommendation = SortedRecommendations[i];
var downloadTask = wc.DownloadFileTaskAsync(new Uri(recommendation.Image.Replace("t.jpg", ".jpg")), tempfilepath);
var continuation = downloadTask.ContinueWith(t => recommendation.Image = tempfilepath);
tasks.Add(continuation);
}
await Task.WhenAll(tasks);