泛型ContinueWith的歧义调用



我正在编写一个简单的c#控制台应用程序,使用异步任务和实体框架(意图在Linux (RHEL)下运行Mono,但这是一个完全不同的挑战)。注意,我的目标是。net 4.0,所以我使用.ContinueWith()而不是await

加上北风数据库的EF DB模型,就是整个应用程序:

using System;
using System.Linq;
using System.Threading.Tasks;
namespace MonoEF
{
    class Program
    {
        private static Model.NorthwindEntities _db = new Model.NorthwindEntities();
        static void Main(string[] args)
        {
            try
            {
                GetCustomerNamesAsync().ContinueWith(t => {
                    if (t.IsFaulted) Console.WriteLine(t.Exception.Flatten.ToString);
                        else if (t.IsCompleted) foreach (string result in t.Result) Console.WriteLine(result);
                    });
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        private static Task<string[]> GetCustomerNamesAsync()
        {
            return Task.Factory.StartNew(() => (from c in _db.Customers select c.ContactName).Distinct().ToArray());
        } 
    }
}

问题是我在.ContinueWith()处得到以下错误:

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

对我来说,调用不应该是模棱两可的,编译器应该更喜欢泛型任务而不是非泛型任务,特别是因为它是GetCustomerNamesAsync()的输出。然而,作为一个VB。. NET开发人员,在这种情况下,我可能依赖Option Infer

我如何显式地让编译器知道我想在c#中使用哪个调用?

尝试显式指定lambda参数类型,如下所示:

.ContinueWith((Task<string[]> t) => { ... })

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

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

如果不指定action的输入类型,编译器无法确定您想要哪种重载。显式地提供action lambda的输入参数类型解决了这种模糊性。


如果编译器可以假设使用Action<Task<TResult>> action的版本,那当然很好。也许其他人有办法让你养成这种行为?


<标题>为后代…

在注释中,你会看到MCattle发现他遇到这个问题只是因为一些编译器的奇怪之处,与他的lambda内部的方法调用上缺少括号有关。一般来说,在将lambda传递给ContinueWith时,不需要显式指定Task<TResult>类型。