2016-05-04 21 views
6

Ho un'attività che esegue un ciclo e ritarda per un intervallo ogni iterazione. Una volta che lo CancellationTokenSource chiama Cancel() voglio il mio codice principale a Wait() per il Task.Delay(interval) per finire e l'attività per uscire dal ciclo prima che il mio codice continui. Pensavo che questo codice avrebbe funzionato, ma non è così.Perché questa attività non finisce prima che il mio codice superi il comando di attesa

Invece il mio codice principale passa il t.Wait() prima che il Loop esca. Perché?

principale Metodo Codice:

var cts = new CancellationTokenSource(); 
CancellationToken ct = cts.Token; 

var t = Task.Run(() => { MyLoopTask(200, ct); }); 

// Prepare information 

cts.Cancel(); 
t.Wait();  

// Send Information 

Task Codice

private async Task MyLoopTask(int interval, CancellationToken cancelToken) 
{ 
    while (!cancelToken.IsCancellationRequested) 
    { 
     Debug.Print(" Still In Loop  "); 
     // Do something 
     await Task.Delay(interval); 
    } 

    Debug.Print(" cancelled  "); 
    //Clean up 
} 
+1

Messaggio per '' cts' e ct' – dotctor

+0

Mi piacerebbe vedere più del codice del metodo principale per capire cosa sta succedendo. –

+0

è abbastanza grande, cercherò di analizzarlo in modo significativo. –

risposta

9

si crea un'attività con Task.Run che spara e dimentica il compito effettivo che si ottiene indietro da MyLoopTask.

Task.Run è ridondante qui. Puoi semplicemente chiamare MyLoopTask e usare l'attività che restituisce.

var t = MyLoopTask(200, ct); 
// ... 
t.Wait(); 

Se avete ancora qualche motivo per usare Task.Run è possibile farlo facendo in modo di attesa del delegato per il compito effettivo di attesa: Codice

var t = Task.Run(async() => await MyLoopTask(200, ct)); 
// ... 
t.Wait();  
+0

Grazie per la risposta. Vedo quello che stai dicendo: Task.Run ha creato un oggetto Task che ha disattivato il mio metodo e poiché tale metodo era anche asincrono, l'oggetto Task Task.Run è stato terminato immediatamente. Ha senso. –

+0

@AdamHeeg Sì. Tecnicamente il 'compito' esterno si completa nel primo punto asincrono del metodo che è la prima volta che attende TaskDelay. – i3arnon

+0

'var t = Task.Run (() => MyLoopTask (200, ct));' funzionerebbe anche. – svick

Problemi correlati