首页 / C# / c# – 将任务字典转换为结果字典
c# – 将任务字典转换为结果字典
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 将任务字典转换为结果字典,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3960字,纯文字阅读大概需要6分钟。
内容图文
![c# – 将任务字典转换为结果字典](/upload/InfoBanner/zyjiaocheng/811/35c8815969e04af8999b26d3bdbd9deb.jpg)
我有一个程序,必须处理许多对象并产生分析.每个分析都会生成一个字符串,并连接字符串以创建报告.报告需要按特定顺序排列结果,但我想异步分析每个项目,所以我通过将所有内容放入字典来管理它,然后我可以在准备最终输出之前对其进行排序.
注意:为了这个例子,我将假装我们正在分析当前程序集中的类型,尽管在我的情况下它比这更复杂.
这样做的基本模式(我认为)将是这样的:
var types = myAssembly.GetTypes();
var tasks = types.ToDictionary( key => key, value => AnalyzeType(value) );
//AnalyzeType() is an async method that returns Task<string>.
现在我们有一个热门任务的字典,在字典创建时可能会或者可能不会完成,因为我没有等待任何事情.
现在得到结果.我该怎么做?
等待
理论上,我所要做的就是等待每项任务; await操作的结果是值本身.但这并没有转换任何东西.
var results = tasks.ToDictionary( k => k.key, async v => await v.Value );
Console.WriteLine(results.GetType().FullName);
输出:
System.Collections.Generic.Dictionary'2[[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Threading.Tasks.Task'1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
我很困惑……我想通过等待在Task前面,c#会将它转换为结果.但我还有一本任务词典.
调用getResult()
另一种方法是使用它:
var results = tasks.ToDictionary( key => key, value => value.GetAwaiter().GetResult() );
Console.WriteLine(results.GetType().FullName);
输出:
System.Collections.Generic.Dictionary'2[[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
所以这似乎得到了我想要的东西,但我不得不删除await关键字,现在我从编译器得到一个警告,该方法将同步执行.
我可以补充一下
await Task.WhenAll(tasks.Select( kvp => kvp.Value));
…控制直到所有任务都完成运行(因为它可能需要一段时间),所以我的整体解决方案是:
await Task.WhenAll(tasks.Select( kvp => kvp.Value));
var results = tasks.ToDictionary( key => key, value => value.GetAwaiter().GetResult() );
Console.WriteLine(results.GetType().FullName);
我觉得有效.但似乎这不是正确的方法;我怀疑调用GetAwaiter().GetResult(),如果不需要,我宁愿不做额外的WhenAll()步骤,也不应该这样做,因为我得到了等待者和结果每个任务都是单独的.
这样做的正确方法是什么?为什么await关键字在我的第一个例子中不起作用?我需要GetResult()吗?如果我这样做,包含等待Task.WhenAll()是一个好主意,还是仅仅依靠GetAwaiter()调用(以后会发生)更好?
Click here for a Fiddle如果您想使用它.
编辑(回答):
谢谢肖恩的正确答案.如果有人想要他们可以放入他们的代码库中的东西,这是一个可推广的扩展方法.
public static async Task<Dictionary<TKey, TResult>> ToResults<TKey,TResult>(this IEnumerable<KeyValuePair<TKey, Task<TResult>>> input)
{
var pairs = await Task.WhenAll
(
input.Select
(
async pair => new { Key = pair.Key, Value = await pair.Value }
)
);
return pairs.ToDictionary(pair => pair.Key, pair => pair.Value);
}
解决方法:
Why didn’t the await keyword work in my first example?
await关键字解包任务< T>在异步方法的上下文中,对类型< T>的基础结果进行操作,并将异步方法的返回值包装回Task中.这就是为什么每个异步方法/函数returns one of void, Task, or Task<T>(注意void只适用于事件).异步方法不返回未包装的值;我们从来没有看到类似public async int SomeMethod()的方法签名,因为返回int不会在异步方法中编译.它需要返回一个Task< int>代替.
What is the right way to do this?
这是一种用于转换具有类型Task< T>的值的字典的方法(with a Fiddle).到类型为< T>的值的字典:
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public async static void Main()
{
// create a dictionary of 10 tasks
var tasks = Enumerable.Range(0, 10)
.ToDictionary(i => i, i => Task.FromResult(i * i));
// await all their results
// mapping to a collection of KeyValuePairs
var pairs = await Task.WhenAll(
tasks.Select(
async pair =>
new KeyValuePair<int, int>(pair.Key, await pair.Value)));
var dictionary = pairs.ToDictionary(p => p.Key);
System.Console.WriteLine(dictionary[2].Value); // 4
}
}
内容总结
以上是互联网集市为您收集整理的c# – 将任务字典转换为结果字典全部内容,希望文章能够帮你解决c# – 将任务字典转换为结果字典所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。