2011-01-12 20 views
9

Quasi tutta la documentazione che ho visto utilizzando C# 4.0 Task.Factory.StartNew afferma che per attendere il completamento dell'attività, è necessario attendere. Ma i miei test iniziali dimostrano che non è necessario. Qualcun altro può darmi conferma su questo? Sono curioso di sapere perché così tanti riferimenti online e stampati dicono che dovresti chiamare Wait.È necessario attendere() dopo aver utilizzato Task.Factory.StartNew()?

Ecco una semplice app per console che mostra che non ho bisogno dell'istruzione Wait, quindi ho commentato. Se commento o meno il tsk.Wait(), l'output è lo stesso.

uscita prevista in tutti i casi è la seguente:

 
Main thread starting. 
After running MyTask. The result is True 
After running SumIt. The result is 1 
Main thread ending. 

Il codice:

class Program 
{ 
    // A trivial method that returns a result and takes no arguments. 
    static bool MyTask() 
    { 
     Thread.Sleep(2000); 
     return true; 
    } 

    // This method returns the summation of a positive integer 
    // which is passed to it. 
    static int SumIt(object v) 
    { 
     int x = (int)v; 
     int sum = 0; 
     for (; x > 0; x--) 
      sum += x; 
     return sum; 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("Main thread starting."); 
     // Construct the first task. 
     Task<bool> tsk = Task<bool>.Factory.StartNew(() => MyTask()); 
     // I found this Wait statement to be completely unnecessary. 
     //tsk.Wait(); 
     Console.WriteLine("After running MyTask. The result is " + 
     tsk.Result); 
     // Construct the second task. 
     Task<int> tsk2 = Task<int>.Factory.StartNew(() => SumIt(1)); 
     Console.WriteLine("After running SumIt. The result is " + 
     tsk2.Result); 
     tsk.Dispose(); 
     tsk2.Dispose(); 
     Console.WriteLine("Main thread ending."); 
     Console.ReadLine(); 
    } 
} 

risposta

19

Se si desidera attendere il completamento dell'attività, la linea di condotta consigliata è chiamare .Wait(). Per un Task (al contrario di un Task<T>) questa è l'unica opzione.

Per un Task<T>, però, c'è anche .Result, che anche attese, e questo è ciò che si sta utilizzando. Quindi nel tuo caso non è necessario chiamare .Wait().

+0

Grazie, Timwi. Ho avuto una scoreggia cerebrale e non ho notato che stavo usando Task anziché Task. Ora ha senso! –

+0

@tambui: che ne dici di contrassegnarlo come una risposta? – stackoverflowuser

+0

@stackoverflowuser: Scusa, non sapevo come. Fatto ora. –

1

Dal momento che in base al this, l'accesso alla Value del Task assicura che l'operazione è completata, si' Ho ragione che non è richiesto.

+0

Questo è corretto. Grazie, Jacob! Il mio errore è stato che ho dimenticato che stavo usando Task anziché Task. –

1

Come ha dichiarato Timwi, .Result attende anche. Poiché stai utilizzando tsk.Result nella tua chiamata Console.WriteLine, stai facendo l'attesa come un effetto collaterale.

Dipende anche da quanto tempo è necessario completare l'attività. Se è molto breve, potrebbe non rendersi conto della necessità di. Attendere, perché sembra terminare sempre in tempo. Esiste il pericolo di lasciarlo fuori se è necessario completare l'attività prima di continuare. Dovrebbe quindi essere utilizzato .Wait anche se il 99% delle volte, in realtà non è necessario attendere in attesa.

2

Una caratteristica importante di Wait è che funge da punto di rendezvous in quanto qualsiasi eccezione generata da Task verrà ripetuta a questo punto. Poiché l'attuale implementazione Task * obbliga a osservare qualsiasi eccezione di questo tipo, Wait è una buona opzione per farlo. Tuttavia, è possibile anche osservare l'eccezione interrogando l'istanza Task per un'eccezione.

*) Apparentemente questo sarà cambiato. Il comportamento è cambiato nel CTP asincrono.

Problemi correlati