2013-04-12 12 views
8

Ho un metodo asincrono che verrà utilizzato in Parallel.Foreach. nel metodo asincrono è atteso un compito. Tuttavia, nel test, sembra che non ci siano comportamenti attesi, l'Attesa Task non è stata completata. Qual è il problema? Di seguito è riportato il codice.attendi in Parallel.foreach

public void method1() 
{ 
    Ilist<string> testList = new IList<string>(){"1","2","3"}; 
    Parallel.ForEach(testList,()=> 
    { 
     method2(); 
    }); 
} 
public async void method2() 
{ 
    await Task.run(()=>{ some other codes here }); 
} 
+0

Questa è la domanda migliore formulata per questo problema, ma una vittima di esso ha la migliore risposta ad esso: http: // StackOverflow .com/a/11565317/176877 –

+0

Non è così: l'esempio di codice mostra che le ipotesi dell'OP su async-await e TPL sono viziate fin dall'inizio, in modo tale da confondere la domanda. –

risposta

2

void async metodi sono 'mordi e fuggi', e non c'è modo di aspettare per loro di completare. Quando method2 viene richiamato nel loop parallelo, viene restituito immediatamente, quindi il loop assicura solo che le attività in method2 vengano create prima del completamento del ciclo.

È possibile modificare il tipo di ritorno di method2 a Task che consente di attendere il risultato dell'operazione, ad es.

public async Task method() 
{ 
    await Task.Run(() { some other code here }); 
} 

quale si può attendere nel vostro ciclo con

method2().Wait(); 

anche se facendo questo non è meglio che correre il corpo del compito in method2 direttamente nel vostro delegato foreach.

+0

Sì, hai ragione, funziona. La ragione per cui devo eseguire in method2 perché devo passare Func diversi al metodo1. come creare, cancellare, ecc. Grazie mille. – user1438980

6

In ritardo per rispondere, ma sembra che si stia tentando di eseguire il lavoro associato alla CPU in parallelo, anziché eseguire il lavoro I/O associato in modo asincrono. Parallel.ForEach si sta prendendo cura del tuo parallelismo, quindi non c'è bisogno di Task.Run, e async/await non ti stanno guadagnando nulla qui. Io suggerirei di rimuovere i bit da method2, quindi il tutto si semplifica in:

public void method1() 
{ 
    Ilist<string> testList = new IList<string>(){"1","2","3"}; 
    Parallel.ForEach(testList,()=> 
    { 
     method2(); 
    }); 
} 
public void method2() 
{ 
    // some other (plain old synchronous) code here 
}