2012-04-05 5 views
8

Mam naprawdę prosty kod:Task.Factory.StartNew() przeciąża

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

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

static int GetInt() 
{ 
    return 64; 
} 

Dlaczego otrzymuję błąd kompilatora dla pierwszego zadania? Podpisy metod (bez parametrów, typ zwrotu to int) są równe, nieprawdaż?

Znam rozwiązanie (które jest dość proste: var task = Task.Factory.StartNew<int>(GetInt);), ale chciałbym wiedzieć, jaki jest problem z powyższym kodem.

+3

Jaki jest błąd kompilatora? –

+0

Proszę spróbować, mam tylko niemiecki tekst o błędzie kompilatora: "Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften:" System.Threading.Tasks.TaskFactory.StartNew (System.Func ) "und" System.Threading. Tasks.TaskFactory.StartNew (System.Action) "" ale to nie ma sensu, ponieważ 'GetInt' zwróci' int' not 'void' – GameScripting

Odpowiedz

3

Otrzymujesz niejednoznaczny błąd połączenia, ponieważ sygnatura metody jest taka sama. Wartości zwracane nie są częścią podpisu.

Ponieważ nie podano wyraźnego typu zwrotu, kompilator nie wie, który z nich podjąć.

Method Signature in C#

+1

Myślę, że naprawdę trzeba przeformułować swoją odpowiedź: Działanie jest bardzo różne niż w przypadku Func . Twoja odpowiedź brzmi obecnie tak, jakby implementacja 'StartNew' nie była nawet kompilowana. – ChrisWue

+0

Zauważam, dziękuję. – Alex

0

Otrzymujesz błąd kompilacji, ponieważ metoda StartNew pobiera działanie (zwraca void) lub Func (zwraca coś), predykaty z różnymi przeciążeniami, a nie bezpośredni delegat.

+1

To brzmi jak odpowiedź "machająca ręką", podając '' dla parametru typu ogólnego w żaden sposób nie uczynić delegata bardziej jak 'działaniu ' lub 'Func ', więc oczywiście jest w stanie wywnioskować, że sam udział. –

+0

Zapewnienie sprawia, że ​​wezwanie całkowicie jednoznaczne. nie ma podpisu 'Task StartNew (Action)'. –

+0

@ LasseV.Karlsen, Nie jestem pewien, dlaczego tak uważasz.Zapobiegam 2 błędom czasu kompilacji podczas kompilacji kodu - pierwszy z nich mówi, że typ zwrotu dla GetInt jest nieprawidłowy, dlatego musisz przepisać wywołanie jako 'code' var task2 = Task.Factory.StartNew (() => GetInt()); 'code', który jest skróconą wersją' code'var task = Task.Factory.StartNew (new Func (GetInt); 'code'. –

1

pomogłoby pokazują wyjątek: „wywołanie jest niejednoznaczna pomiędzy następującymi sposobami lub właściwości" System.Threading.Tasks.TaskFactory.StartNew (System.Action) „i System.Threading .Tasks.TaskFactory.StartNew (System.Func) "”

Jeśli spojrzeć istnieją dwa możliwe sposoby:

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

jeśli dodać <int> lub dostaw a Func<int> zmuszasz go do zrobienia pierwszego podpisu. Bez tego twój kod jest niejednoznaczny.

0

Jak napisali inni, musisz przekazać GetInt jako funkcję StartNew lub określić, że zamierzasz zwrócić wartość z StartNew przez podanie ogólnego typu. W przeciwnym razie kompilator nie ma pojęcia, jakiego rodzaju zadanie zamierzasz utworzyć ... jest niejednoznaczny.

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

Dla przypomnienia, oto jeszcze dwa sposoby na zrobienie go (czyli kompilacji):

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

Ponieważ kompilator nie może zdecydować, które z tych dwóch przeciążeń używać:

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

Powodem tego jest to, że typ zwracany nie jest częścią rozdzielczości przeciążenia w języku C# (tak samo jak nie można mieć dwóch przeciążeń różniących się tylko typami zwrotów), a zatem kompilator nie może zdecydować, czy GetInt powinien być Action lub Func<T>. Wymuszenie użycia wersji ogólnej przez wywołanie StartNew<int>(GetInt) dostarczy wymaganych informacji.

+0

To detfinfly najlepsze rozwiązanie. –