UserState使用Web客户端和TaskAsync下载从异步CTP(UserState usin

2019-10-31 23:18发布

我目前正在与异步CTP工作,需要将这些代码转换成代码,我可以用Task.WhenAll()。

我所做的到现在用的是UserState对象,并把我的标识符(AID)到它,然后在完成事件中使用它。

然而,wc.DownloadFileTaskAsync梅索德没有与UserState过载。 我能做什么?

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

这基本上是什么我想出了,但我在y.Aid得到一个出OUF越界异常== SortedRecommendations [I] .Aid因为我现在是obvioulsy别的东西,然后它是当下载开始。 唯一的可能我看到的是使用类似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

Answer 1:

首先,我认为你不应该立足于IDS的逻辑(除非你真的需要)。 您应该使用在该对象的引用SortedRecommendations集合。

现在,如果你想只下载一个文件的时间,你可以简单地使用await

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

但是,如果你想开始所有下载的同时,比如你DownloadFileAsync()代码执行,你可以使用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);

最好的解决方案可能会下载的文件的数量有限,在一次,而不是一个或全部。 这样做是比较复杂的,一个解决方案是使用ActionBlock从TPL数据流与MaxDegreeOfParallelism集。



文章来源: UserState using WebClient and TaskAsync download from Async CTP