UserState使用Web客户端和下载TaskAsync从异步CTP [英] UserState using WebClient and TaskAsync download from Async CTP

查看:267
本文介绍了UserState使用Web客户端和下载TaskAsync从异步CTP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在与异步CTP工作,需要把这个code转换为code,我可以用Task.WhenAll()。

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

然而wc.DownloadFileTaskAsync梅索德不具有与UserState过载。我该怎么办?

 的for(int i = 0; I< SortedRecommendations.Count;我++)
{
    字符串tempfilepath =文件路径+ SortedRecommendations [I] .Aid +.JPG;    如果(File.Exists(tempfilepath))
        继续;    WebClient的WC =新的WebClient();
    wc.DownloadFileCompleted + =(S,E)=>
        {
            变种Q = SortedRecommendations.Where(X => x.Aid ==(INT)e.UserState);
            如果(q.Count()大于0)
                。q.First()图像= tempfilepath;
        };
    wc.DownloadFileAsync(新的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;我++)
{
    字符串tempfilepath =文件路径+ SortedRecommendations [I] .Aid +.JPG;    如果(File.Exists(tempfilepath))
        继续;    WebClient的WC =新的WebClient();
    wc.DownloadFileCompleted + =(S,E)=>
    {
        变种Q = SortedRecommendations.Where(X => x.Aid == SortedRecommendations [I] .Aid);
        如果(q.Count()大于0)
            。q.First()图像= tempfilepath;    };
    tasks.Add(wc.DownloadFileTaskAsync(新的URI(SortedRecommendations [I] .Image.Replace(t.jpg,.JPG)),tempfilepath));
}等待TaskEx.WhenAll(任务);
//完成一切


解决方案

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

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

 的for(int i = 0; I< SortedRecommendations.Count;我++)
{
    字符串tempfilepath =文件路径+ SortedRecommendations [I] .Aid +.JPG;    如果(File.Exists(tempfilepath))
        继续;    WebClient的WC =新的WebClient();
    VAR推荐= SortedRecommendations [I]
    等待wc.DownloadFileTaskAsync(新的URI(recommendation.Image.Replace(t.jpg,.JPG)),tempfilepath);
    recommendation.Image = tempfilepath;
}

但是,如果你想开始的所有下载内容在同一时间,喜欢你的 DownloadFileAsync() code呢,你可以使用 ContinueWith()来代替。而你并不需要用户状态,这就是闭包是:

 的for(int i = 0; I< SortedRecommendations.Count;我++)
{
    字符串tempfilepath =文件路径+ SortedRecommendations [I] .Aid +.JPG;    如果(File.Exists(tempfilepath))
        继续;    WebClient的WC =新的WebClient();
    VAR推荐= SortedRecommendations [I]
    VAR downloadTask = wc.DownloadFileTaskAsync(新的URI(recommendation.Image.Replace(t.jpg,.JPG)),tempfilepath);
    VAR延续= downloadTask.ContinueWith(T => recommendation.Image = tempfilepath);
    tasks.Add(续)
}等待Task.WhenAll(任务);

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

I'm currently working with the Async CTP and need to convert this code into code where I can use Task.WhenAll().

What I did until now was using the UserState object and put my identifier (AID) into it and then use it in the completed event.

However the wc.DownloadFileTaskAsync methode doesn't have an overload with UserState. What can I do?

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

This is basically with what I came up with, however I'm getting a out ouf bounds exception at y.Aid == SortedRecommendations[i].Aid because i is now obvioulsy something else then it was when the download started. Only other possibility I see is using something like TaskEx.Run( () => { // download data synchronously }; but I don't like this approach.

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

解决方案

First, I think you shouldn't base your logic on ids (unless you really have to). You should use references to the objects in the SortedRecommendations collection.

Now, if you wanted to download only one file at a time, you could simply use 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;
}

But, if you wanted to start all of the downloads at the same time, like your DownloadFileAsync() code does, you could use ContinueWith() instead. And you don't need user state, that's what closures are for:

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

The best solution would probably be to download a limited number of files at once, not one or all of them. Doing that is more complicated and one solution would be to use ActionBlock from TPL Dataflow with MaxDegreeOfParallelism set.

这篇关于UserState使用Web客户端和下载TaskAsync从异步CTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆