2012-12-18 16 views
7

Ho letto che un 'BackgroundWorker' è designed to be replaced di Ansyc/Attesa.Un'attesa rende il resto del metodo asincrono?

Perché mi piace l'aspetto condensato di Async/Attesa, sto iniziando a convertire alcuni dei miei BackgroundWorkers in chiamate Async/Await.

Questo è un esempio del codice che ho (chiamato dall'interfaccia utente):

public async void RunFromTheUI() 
{ 
    await OtherAction(); 
} 

public async void OtherAction() 
{ 
    var results = await services.SomeRemoteAction(); 

    foreach (var result in results) 
    { 
     result.SemiIntenseCalculation(); 
     Several(); 
     Other(); 
     NonAsync(); 
     Calls(); 
    } 

    SomeFileIO(); 
} 

Quando chiamo RunFromTheUI tornerà quasi immediatamente (come da Async e attendono design).

Ma quando riprende dopo services.SomeRemoteAction() termina ha un ciclo foreach e un'altra chiamata al metodo da eseguire.

La mia domanda è: Se quel loop è un maiale performante congelerà l'interfaccia utente? (Prima avevo tutto in un thread di lavoro in background, quindi non rallentava l'interfaccia utente).

Nota: il mio obiettivo è .Net 4.0 e utilizzo del pacchetto Async Nuget.

+0

async/await e BackgroundWorker risolvono due diversi problemi. BG worker è più precisamente sostituito da Tasks. Async li sostituisce solo quando il codice del corpo lavoratore è praticamente inattivo, in cui BGW/Attività sono ancora utili quando è necessario eseguire operazioni di sollevamento pesi. Sembra che tu stia aspettando i risultati del servizio nella tua domanda, solo FYI. –

+0

1. Il tuo codice non verrà compilato, non puoi 'attendere 'un metodo' async void'. 2. Dovresti evitare di usare i metodi 'async void', non possono essere' attendi'ed e rendere più difficile la gestione delle eccezioni. – svick

risposta

6

La mia domanda è: se quel ciclo è un maiale performante congelerà l'interfaccia utente?

Sì, lo sarà. Il resto del metodo asincrono verrà comunque eseguito sul thread dell'interfaccia utente al termine dell'azione remota. Se non si desidera che ciò accada, allora le opzioni sono:

  • Usa ConfigureAwait(continueOnCapturedContext: false) in modo che la continuazione non non eseguire sul thread UI
  • Esegue tutto il metodo in un thread diverso per cominciare, usando Task.Run. (Potresti comunque renderlo un metodo asincrono, per evitare il blocco di un thread quando non ne hai bisogno.)

In sostanza, se hai un carico di chiamate sincrone o di blocco o di lavoro intensivo della CPU , si desidera evitare che ciò accada sul thread dell'interfaccia utente, che è l'opposto di ciò che async/await esegue per impostazione predefinita.

+1

'Task.Run' ha impostazioni predefinite migliori di' Task.Factory.StartNew' se si utilizza 'async'. [Stephen Toub entra nei dettagli.] (Http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) –

+0

@StephenCleary: risolto, grazie. Non stavo prestando attenzione - 'Task.StartNew' non era valido per iniziare, ovviamente :) –

+0

Jon: Qualunque buon punto di partenza per leggere/capire async/attendere, compito? – shahkalpesh

Problemi correlati