2012-04-05 21 views
8

Tengo código muy simple:Task.Factory.StartNew() sobrecargas

static void Main(string[] args) 
{ 
    var task = Task.Factory.StartNew(GetInt); 

    var task2 = Task.Factory.StartNew(
     () => 
     { 
      return GetInt(); 
     }); 
} 

static int GetInt() 
{ 
    return 64; 
} 

¿Por qué recibo un error de compilación para la primera tarea? Las firmas de método (sin params, tipo de devolución es int) son iguales, ¿verdad?

Conozco una solución (que es bastante simple: var task = Task.Factory.StartNew<int>(GetInt);) pero me gustaría saber cuál es el problema con el código anterior.

+3

¿Cuál es el error del compilador? –

+0

Por favor, pruébelo usted mismo, solo tengo el texto de error del compilador alemán: 'El Aumento de la información no está disponible para las versiones anteriores y las siguientes: 'System.Threading.Task.TaskFactory.StartNew (System.Func )' und 'System.Threading. Tasks.TaskFactory.StartNew (Sistema.Acción) "' pero no tiene sentido porque 'GetInt' devolverá' int' no 'void' – GameScripting

Respuesta

3

Recibirá un error de llamada ambiguo porque la firma del método es la misma. Los valores devueltos no son parte de la firma.

Dado que no proporciona un tipo de devolución explícita, el compilador no sabe qué tomar.

Method Signature in C#

+1

Creo que realmente necesita reformular su respuesta: Acción es un tipo muy diferente a Func . Su respuesta actualmente se lee como si la implementación 'StartNew' ni siquiera compilara. – ChrisWue

+0

Conocido, gracias. – Alex

0

Obtiene el error de compilación porque el método StartNew toma un predicado de Acción (devuelve vacío) o Func (devuelve algo) con sus varias sobrecargas, y no un delegado directo.

+1

Eso suena como una respuesta" agitando la mano ", proporcionando' 'para el parámetro de tipo genérico no de ninguna manera hacer que el delegado más como 'Acción ' o 'Func ', así que obviamente es capaz de deducir esa parte sí. –

+0

Proporcionar hace la llamada de ambigüedad. no hay ninguna firma 'Tarea StartNew (Acción)'. –

+0

@ LasseV.Karlsen, No estoy seguro de por qué lo pensaría. Recibo 2 errores de compilación cuando compilo el código - el primero dice que el tipo de devolución para GetInt no es correcto. Por lo tanto, necesita volver a escribir la llamada como 'código' var task2 = Task.Factory.StartNew (() => GetInt()); 'code' que es la versión abreviada de' code'var task = Task.Factory.StartNew (new Func (GetInt); 'código'. –

1

ayudarán a demostrar la excepción: "La llamada es ambigua entre los métodos o propiedades siguientes: 'System.Threading.Tasks.TaskFactory.StartNew (System.Action)' y 'System.Threading .Tasks.TaskFactory.StartNew (System.Func) '"

Si se echa un vistazo, hay dos métodos posibles:

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

si agrega el <int> o suministro a Func<int> lo fuerza a tomar la primera firma. Sin eso, tu código es ambiguo.

0

Según lo expresado por otros, debe pasar GetIn como una función a StartNew, o especificar que tiene la intención de devolver un valor de StartNew proporcionando el tipo genérico. De lo contrario, el compilador no tiene idea de qué tipo de tarea tiene la intención de crear ... es ambigua.

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

    var task2 = Task.Factory.StartNew(
     () => 
     { 
      return GetInt(); 
     }); 
} 

static int GetInt() 
{ 
    return 64; 
} 
1

Para el registro, aquí hay dos maneras más de hacerlo (que compilación):

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

Debido a que el compilador no puede decidir cuál de estos dos sobrecargas de uso:

StartNew(Action) 
StartNew<TResult>(Func<TResult>) 

El motivo es que el tipo de devolución no forma parte de la resolución de sobrecarga en C# (de la misma manera que no puede tener dos sobrecargas que difieran solo en los tipos de devolución) y, por lo tanto, el compilador no puede decidir si GetInt debe ser Action o Func<T>. Obligar a utilizar la versión genérica llamando al StartNew<int>(GetInt) proporcionará la información requerida.

+0

Esto es definfly la mejor solución. –

Cuestiones relacionadas