2012-04-05 15 views
8

io ho il codice molto semplice:Task.Factory.StartNew() Sovraccarichi

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

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

static int GetInt() 
{ 
    return 64; 
} 

Perché ricevo un errore di compilazione per il primo compito? Le firme del metodo (nessun parametro, tipo di ritorno è int) sono uguali, vero?

Conosco una soluzione (che è piuttosto semplice: var task = Task.Factory.StartNew<int>(GetInt);) ma mi piacerebbe sapere qual è il problema con il codice sopra.

+3

Qual è l'errore del compilatore? –

+0

Si prega di provare, ho solo il testo errore del compilatore tedesco: 'Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften:" System.Threading.Tasks.TaskFactory.StartNew (System.Func ) "und" System.Threading. Tasks.TaskFactory.StartNew (sistema.Azione) "' ma non ha senso perché 'GetInt' restituirà' int' not 'void' – GameScripting

risposta

3

Si ottiene un errore di chiamata ambiguo perché la firma del metodo è la stessa. I valori di ritorno non fanno parte della firma.

Dato che non si fornisce un tipo di reso esplicito, il compilatore non sa quale prendere.

Method Signature in C#

+1

Penso che sia davvero necessario riformulare la risposta: l'azione è molto diversa da Func . La tua risposta al momento si legge come se l'implementazione di 'StartNew' non dovesse nemmeno essere compilata. – ChrisWue

+0

Notato, grazie. – Alex

0

Si ottiene l'errore di compilazione perché il metodo StartNew accetta un predicato Action (restituisce void) o Func (restituisce qualcosa) con i suoi vari overload e non un delegato diretto.

+1

Che suona come una risposta" mano-ondeggiante ", fornendo' ' per il parametro di tipo generico non in alcun modo rendere il delegato più come 'azione ' o 'Func ', quindi ovviamente è in grado di dedurre che parte per sé. –

+0

Fornire effettua la chiamata del tutto inequivocabile. non v'è alcuna firma 'Task StartNew (Azione)'. –

+0

@ LasseV.Karlsen, Non sono sicuro del motivo per cui lo penseresti, ricevo 2 errori di compilazione durante la compilazione del codice: il primo dice che il tipo restituito per GetInt non è corretto, quindi è necessario riscrivere la chiamata come 'code' var task2 = Task.Factory.StartNew (() => GetInt()); 'codice' che è la versione abbreviata di' code'var task = Task.Factory.StartNew (new Func (GetInt); 'codice'. –

1

contribuirebbe a dimostrare l'eccezione: "La chiamata è ambiguo tra i seguenti metodi o proprietà: 'System.Threading.Tasks.TaskFactory.StartNew (System.Action)' e 'System.Threading .Tasks.TaskFactory.StartNew (System.Func) '"

Se si dà un'occhiata ci sono due metodi possibili:

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

Se si aggiunge il <int> o fornitura a Func<int> si forza a prendere la prima firma. Senza questo il tuo codice è ambiguo.

0

Come indicato da altri, è necessario passare in GetInt come una funzione a StartNew oppure specificare che si intende restituire un valore da StartNew fornendo il tipo generico. Altrimenti, il compilatore non ha idea del tipo di attività che si intende creare ... è ambiguo.

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

Per la cronaca, qui ci sono altri due modi di farlo (che compilazione):

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

Poiché il compilatore non può decidere quale di questi due overload da usare:

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

Il motivo è che il tipo restituito non fa parte della risoluzione di sovraccarico in C# (come non è possibile avere due sovraccarichi solo diversi nei tipi restituiti) e quindi il compilatore non può decidere se GetInt dovrebbe essere un Action o un Func<T>. Forcing per utilizzare la versione generica chiamando StartNew<int>(GetInt) fornirà le informazioni richieste.

+0

Questa è detfinfly la soluzione migliore. –

Problemi correlati