I've got really simple code:
static void Main(string[] args)
{
var task = Task.Factory.StartNew(GetInt);
var task2 = Task.Factory.StartNew(
() =>
{
return GetInt();
});
}
static int GetInt()
{
return 64;
}
Why do I get a compiler error for the first task?
The method signatures (no params, return type is int
) are equal, aren't they?
I know a solution(which is quite simple: var task = Task.Factory.StartNew<int>(GetInt);
) but I'd like to know whats the problem with the code above.
Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften: "System.Threading.Tasks.TaskFactory.StartNew<int>(System.Func<int>)" und "System.Threading.Tasks.TaskFactory.StartNew(System.Action)"
but it doesn't make sense cause GetInt
will return int
not void
GameScripting 2012-04-05 19:02
You get an ambiguous call error because the method signature is the same. Return values are not part of the signature.
Since you don't provide an explicit return type, the compiler doesn't know which to take.
StartNew
implementation should not even compile - ChrisWue 2012-04-05 19:07
Because the compiler cannot decide which of these two overloads to use:
StartNew(Action)
StartNew<TResult>(Func<TResult>)
The reason for that is that the return type is not part of the overload resolution in C# (same way as you can't have two overloads only differing in return types) and therefore the compiler cannot decide whether GetInt
should be an Action
or a Func<T>
. Forcing to use the generic version by calling StartNew<int>(GetInt)
will provide the required information.
For the record, here are two more ways of doing it (that compile):
var task3 = Task.Factory.StartNew((Func<int>)GetInt);
var task4 = Task.Factory.StartNew(() => GetInt());
Would help to show the exception: "The call is ambiguous between the following methods or properties: 'System.Threading.Tasks.TaskFactory.StartNew(System.Action)' and 'System.Threading.Tasks.TaskFactory.StartNew(System.Func)'"
If you take a look there are two possible methods:
public Task<TResult> StartNew<TResult>(Func<TResult> function);
public Task StartNew(Action action);
If you add the <int>
or supply a Func<int>
you force it to take the first signature. Without that your code is ambiguous.
You get the compile error because the StartNew method takes in either an Action (returns void) or a Func (returns something) predicates with it's various overloads, and not a direct delegate.
<int>
for the generic type parameter does not in any way make the delegate more like Action<T>
or Func<T>
, so obviously it is able to deduce that part itself - Lasse Vågsæther Karlsen 2012-04-05 18:59
Task<TResult> StartNew<TResult>(Action)
- Ian Mercer 2012-04-05 19:04
code
var task2 = Task.Factory.StartNew(() => GetInt());code
which is the abbreviated version of code
var task = Task.Factory.StartNew(new Funccode
- Scorpion-Prince 2012-04-05 19:15
As stated by others, you need to pass in GetInt as a function to StartNew, or specify that you intend to return a value from StartNew by supplying the generic type. Otherwise, the compiler has no idea what kind of task you intend to create....it is ambiguous.
static void Main(string[] args)
{
var task = Task.Factory.StartNew<int>(GetInt);
var task2 = Task.Factory.StartNew(
() =>
{
return GetInt();
});
}
static int GetInt()
{
return 64;
}