c#-4.0 – 对通用ContinueWith的模糊调用

前端之家收集整理的这篇文章主要介绍了c#-4.0 – 对通用ContinueWith的模糊调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个简单的C#控制台应用程序,该应用程序使用异步任务和实体框架(意图使用Mono在 Linux(RHEL)下运行它,但这是另一个挑战).请注意,我的目标是.NET 4.0,所以我使用的是.ContinueWith()而不是await.

这个以及Northwind数据库的EF DB模型是整个应用程序:

  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4.  
  5. namespace MonoEF
  6. {
  7. class Program
  8. {
  9. private static Model.NorthwindEntities _db = new Model.NorthwindEntities();
  10.  
  11. static void Main(string[] args)
  12. {
  13. try
  14. {
  15. GetCustomerNamesAsync().ContinueWith(t => {
  16. if (t.IsFaulted) Console.WriteLine(t.Exception.Flatten.ToString);
  17. else if (t.IsCompleted) foreach (string result in t.Result) Console.WriteLine(result);
  18. });
  19.  
  20. Console.ReadLine();
  21. }
  22. catch (Exception ex)
  23. {
  24. Console.WriteLine(ex.ToString());
  25. }
  26. }
  27.  
  28. private static Task<string[]> GetCustomerNamesAsync()
  29. {
  30. return Task.Factory.StartNew(() => (from c in _db.Customers select c.ContactName).Distinct().ToArray());
  31. }
  32.  
  33. }
  34. }

问题是我在.ContinueWith()收到以下错误

  1. Ambiguous Invocation:
  2. System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task<string[]>>) (in class Task<string[]>)
  3. System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task>) (in class Task)
  4. match

对我来说,调用不应该是模糊的,编译器应该优先使用非泛型Task上的泛型Task,特别是因为它是GetCustomerNamesAsync()的输出.但是,作为VB.NET开发人员,我可能在这种情况下依赖于Option Infer.

我如何明确地让编译器知道我希望它在C#中使用哪个调用

解决方法

尝试显式指定lambda参数类型,如下所示:
  1. .ContinueWith((Task<string[]> t) => { ... })

调用它的方式存在的问题是Task< TResult>和Task(它的基类)都有一个看起来几乎相同的ContinueWith方法

  1. Task<TResult>.ContinueWith(Action<Task<TResult>> action)
  2. Task<TResult>.ContinueWith(Action<Task> action) //inherited from `Task`

如果不指定操作的输入类型,编译器无法确定所需的过载.明确地提供动作lambda的输入参数类型可以解决这种歧义.

如果编译器可以采用采取Action< Task< TResult>>的版本,那肯定会很好.行动.也许其他人对如何获得这种行为有所了解?

后人……

评论中你会看到MCattle发现他只是遇到了这个问题,因为一些编译器奇怪与他在lambda内的方法调用中缺少括号有关.通常,您不需要明确指定任务< TResult>将lambda传递给ContinueWith时输入.

猜你在找的C#相关文章