Task.Factory.StartNew() overloads

本文关键字:overloads StartNew Factory Task | 更新日期: 2023-09-27 18:30:23

我有非常简单的代码:

static void Main(string[] args)
{
    var task = Task.Factory.StartNew(GetInt);
    var task2 = Task.Factory.StartNew(
        () =>
        {
            return GetInt();
        });
}
static int GetInt()
{
    return 64;
}

为什么第一个任务会出现编译器错误?方法签名(没有参数,返回类型为 int )是相等的,不是吗?

我知道一个解决方案(非常简单:var task = Task.Factory.StartNew<int>(GetInt);),但我想知道上面的代码有什么问题。

Task.Factory.StartNew() overloads

您会收到一个不明确的调用错误,因为方法签名是相同的。返回值不是签名的一部分。

由于您没有提供显式返回类型,因此编译器不知道要采用哪种返回类型。

C# 中的方法签名

因为编译器无法决定使用这两个重载中的哪一个:

StartNew(Action)
StartNew<TResult>(Func<TResult>)
原因是

返回类型不是 C# 中重载解析的一部分(就像您不能有两个重载只是返回类型不同一样),因此编译器无法决定GetInt应该是Action还是Func<T>。通过调用 StartNew<int>(GetInt) 强制使用通用版本将提供所需的信息。

作为记录,这里有另外两种方法(编译):

var task3 = Task.Factory.StartNew((Func<int>)GetInt);
var task4 = Task.Factory.StartNew(() => GetInt());

有助于显示异常:"调用在以下方法或属性之间不明确:"System.Threading.Tasks.TaskFactory.StartNew(System.Action)"和"System.Threading.Tasks.TaskFactory.StartNew(System.Func)"

如果你看一下,有两种可能的方法:

public Task<TResult> StartNew<TResult>(Func<TResult> function);
public Task StartNew(Action action);

如果添加<int>或提供Func<int>则强制其采用第一个签名。 没有它,你的代码是模棱两可的。

您会收到编译错误,因为 StartNew 方法采用 Action(返回 void)或 Func(返回某些内容)谓词,其中包含各种重载,而不是直接委托。

如其他人所述,您需要将 GetInt 作为函数传递给 StartNew,或者指定您打算通过提供泛型类型从 StartNew 返回值。 否则,编译器不知道您打算创建哪种任务。这是模棱两可的。

static void Main(string[] args)
{
    var task = Task.Factory.StartNew<int>(GetInt);
    var task2 = Task.Factory.StartNew(
        () =>
        {
            return GetInt();
        });
}
static int GetInt()
{
    return 64;
}