C# 解析两个异步代码示例

C# 解析两个异步代码示例,c#,asynchronous,C#,Asynchronous,我需要从URL列表返回一个字典 我有一个代码示例,它正确地异步执行,但只返回一个列表,还有一个代码示例似乎正确地强制转换了对象,但抛出了线程错误 //Seems to assign to the output type correctly, but doesn't execute properly async Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls) {

我需要从URL列表返回一个
字典

我有一个代码示例,它正确地异步执行,但只返回一个
列表
,还有一个代码示例似乎正确地强制转换了对象,但抛出了线程错误

//Seems to assign to the output type correctly, but doesn't execute properly
async Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls)
{
    Dictionary<Uri, Task<byte[]>> dictionary;

    using (var client = new WebClient())
    {
        dictionary = urls.Select(url => new Uri(url)).ToDictionary(
            uri => uri, client.DownloadDataTaskAsync);
        await Task.WhenAll(dictionary.Values);
    }

    return dictionary.ToDictionary(pair => Path.GetFileName(pair.Key.ToString()), pair => pair.Value.Result);
}

//Executes properly, but isn't returning the right output type
async Task<List<byte[]>> ReturnFileData2(IEnumerable<string> urls)
{
    Dictionary<Uri, Task<byte[]>> dictionary;
    var tasks = urls.Select(uri => new WebClient().DownloadDataTaskAsync(uri));
    var results = await Task.WhenAll(tasks);

    return results.Select(result => result).ToList();
}
//似乎正确分配了输出类型,但执行不正确
异步任务ReturnFileData(IEnumerable URL)
{
字典;
使用(var client=new WebClient())
{
字典=url。选择(url=>新Uri(url)).ToDictionary(
uri=>uri,client.DownloadDataTaskAsync);
wait Task.WhenAll(dictionary.Values);
}
返回dictionary.ToDictionary(pair=>Path.GetFileName(pair.Key.ToString()),pair=>pair.Value.Result);
}
//正确执行,但未返回正确的输出类型
异步任务ReturnFileData2(IEnumerable URL)
{
字典;
var tasks=url.Select(uri=>newWebClient().DownloadDataTaskAsync(uri));
var结果=等待任务.WhenAll(任务);
返回结果。选择(result=>result).ToList();
}

如何获取
ReturnFileData2()
并将其修复为将
Uri的文件名与输出中返回的
byte[]
一起强制转换?

您应该坚持使用ReturnFileData,但要对其进行修改,以便为每个URL使用单独的客户端:

async Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls)
{
    Dictionary<Uri, Task<byte[]>> dictionary = urls
        .Select(url => new Uri(url))
        .ToDictionary(uri => uri, GetTheDataAsync);

    await Task.WhenAll(dictionary.Values);

    return dictionary
        .ToDictionary(
            pair => Path.GetFileName(pair.Key.ToString()),
            pair => pair.Value.Result);
}

async Task<byte[]> GetTheDataAsync(Uri uri)
{
    using (var client = new WebClient())
    {
        return await client.DownloadDataTaskAsync(uri);
    }
}
异步任务返回文件数据(IEnumerable URL)
{
字典=URL
.选择(url=>新Uri(url))
.ToDictionary(uri=>uri,GetTheDataAsync);
wait Task.WhenAll(dictionary.Values);
返回字典
.ToDictionary(
pair=>Path.GetFileName(pair.Key.ToString()),
pair=>pair.Value.Result);
}
异步任务GetTheDataAsync(Uri)
{
使用(var client=new WebClient())
{
返回wait client.DownloadDataTaskAsync(uri);
}
}

您应该坚持使用ReturnFileData,但要对其进行修改,以便为每个URL使用单独的客户端:

async Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls)
{
    Dictionary<Uri, Task<byte[]>> dictionary = urls
        .Select(url => new Uri(url))
        .ToDictionary(uri => uri, GetTheDataAsync);

    await Task.WhenAll(dictionary.Values);

    return dictionary
        .ToDictionary(
            pair => Path.GetFileName(pair.Key.ToString()),
            pair => pair.Value.Result);
}

async Task<byte[]> GetTheDataAsync(Uri uri)
{
    using (var client = new WebClient())
    {
        return await client.DownloadDataTaskAsync(uri);
    }
}
异步任务返回文件数据(IEnumerable URL)
{
字典=URL
.选择(url=>新Uri(url))
.ToDictionary(uri=>uri,GetTheDataAsync);
wait Task.WhenAll(dictionary.Values);
返回字典
.ToDictionary(
pair=>Path.GetFileName(pair.Key.ToString()),
pair=>pair.Value.Result);
}
异步任务GetTheDataAsync(Uri)
{
使用(var client=new WebClient())
{
返回wait client.DownloadDataTaskAsync(uri);
}
}

我建议您使用更新的
HttpClient

async Task<Dictionary<string, byte[]>> ReturnFileDataAsync(IEnumerable<string> urls)
{
  Dictionary<string, Task<byte[]>> dictionary;

  using (var client = new HttpClient())
  {
    dictionary = urls.ToDictionary(uri => uri, client.GetByteArrayAsync);
    await Task.WhenAll(dictionary.Values);
  }

  return dictionary.ToDictionary(pair => Path.GetFileName(pair.Key), pair => pair.Value.Result);
}
async任务ReturnFileDataAsync(IEnumerable URL)
{
字典;
使用(var client=new HttpClient())
{
dictionary=url.ToDictionary(uri=>uri,client.GetByteArrayAsync);
wait Task.WhenAll(dictionary.Values);
}
返回dictionary.ToDictionary(pair=>Path.GetFileName(pair.Key),pair=>pair.Value.Result);
}
尽管我可能会这样写,避免使用中间字典:

async Task<Dictionary<string, byte[]>> ReturnFileDataAsync(IEnumerable<string> urls)
{
  using (var client = new HttpClient())
  {
    var results = await Task.WhenAll(urls.Select(async url => new
    {
      Key = Path.GetFileName(url), 
      Value = await client.GetByteArrayAsync(url),
    }));
    return results.ToDictionary(x => x.Key, x => x.Value);
  }
}
async任务ReturnFileDataAsync(IEnumerable URL)
{
使用(var client=new HttpClient())
{
var results=await Task.WhenAll(url.Select)(异步url=>new
{
Key=Path.GetFileName(url),
Value=wait client.GetByteArrayAsync(url),
}));
返回results.ToDictionary(x=>x.Key,x=>x.Value);
}
}

我建议您使用更新的
HttpClient

async Task<Dictionary<string, byte[]>> ReturnFileDataAsync(IEnumerable<string> urls)
{
  Dictionary<string, Task<byte[]>> dictionary;

  using (var client = new HttpClient())
  {
    dictionary = urls.ToDictionary(uri => uri, client.GetByteArrayAsync);
    await Task.WhenAll(dictionary.Values);
  }

  return dictionary.ToDictionary(pair => Path.GetFileName(pair.Key), pair => pair.Value.Result);
}
async任务ReturnFileDataAsync(IEnumerable URL)
{
字典;
使用(var client=new HttpClient())
{
dictionary=url.ToDictionary(uri=>uri,client.GetByteArrayAsync);
wait Task.WhenAll(dictionary.Values);
}
返回dictionary.ToDictionary(pair=>Path.GetFileName(pair.Key),pair=>pair.Value.Result);
}
尽管我可能会这样写,避免使用中间字典:

async Task<Dictionary<string, byte[]>> ReturnFileDataAsync(IEnumerable<string> urls)
{
  using (var client = new HttpClient())
  {
    var results = await Task.WhenAll(urls.Select(async url => new
    {
      Key = Path.GetFileName(url), 
      Value = await client.GetByteArrayAsync(url),
    }));
    return results.ToDictionary(x => x.Key, x => x.Value);
  }
}
async任务ReturnFileDataAsync(IEnumerable URL)
{
使用(var client=new HttpClient())
{
var results=await Task.WhenAll(url.Select)(异步url=>new
{
Key=Path.GetFileName(url),
Value=wait client.GetByteArrayAsync(url),
}));
返回results.ToDictionary(x=>x.Key,x=>x.Value);
}
}