Nos últimos dias, testei os novos recursos do .net 4.5 e c # 5.
Eu gosto de seus novos recursos assíncronos / aguardados. Anteriormente, eu havia usado o BackgroundWorker para lidar com processos mais longos em segundo plano com a interface do usuário responsiva.
Minha pergunta é: depois de ter esses novos recursos, quando devo usar async / waitit e quando um BackgroundWorker ? Quais são os cenários comuns para ambos?
Respostas:
assíncrono / espera é projetado para substituir construções como o
BackgroundWorker
. Embora você certamente possa usá-lo, se quiser, poderá usar async / waitit, juntamente com algumas outras ferramentas TPL, para lidar com tudo o que existe por aí.Como os dois funcionam, tudo se resume à preferência pessoal sobre a qual você usa quando. O que é mais rápido para você ? O que é mais fácil para você entender?
fonte
async
/await
também permite programação assíncrona sem threads do conjunto de threads.É provável que TL; DR para muitos, mas acho que comparar
await
comBackgroundWorker
é como comparar maçãs e laranjas e meus pensamentos sobre isso a seguir:BackgroundWorker
destina-se a modelar uma única tarefa que você deseja executar em segundo plano, em um thread do conjunto de threads.async
/await
É uma sintaxe para de forma assíncrona aguardando em operações assíncronas. Essas operações podem ou não usar um encadeamento de conjunto de encadeamentos ou até mesmo usar outro encadeamento . Então, são maçãs e laranjas.Por exemplo, você pode fazer algo como o seguinte com
await
:Mas, você provavelmente nunca modelaria isso em um trabalhador em segundo plano, provavelmente faria algo assim no .NET 4.0 (antes
await
):Observe a disjunção do descarte comparada entre as duas sintaxes e como você não pode usar
using
semasync
/await
.Mas você não faria algo assim com
BackgroundWorker
.BackgroundWorker
geralmente é para modelar uma única operação de longa duração que você não deseja afetar a capacidade de resposta da interface do usuário. Por exemplo:Não há realmente nada lá com o qual você possa usar async / waitit
BackgroundWorker
esteja criando o thread para você.Agora, você pode usar o TPL:
Nesse caso, o
TaskScheduler
está criando o encadeamento para você (assumindo o padrãoTaskScheduler
) e pode ser usado daawait
seguinte maneira:Na minha opinião, uma grande comparação é se você está relatando progresso ou não. Por exemplo, você pode ter
BackgroundWorker like
isso:Mas você não lidaria com isso porque arrastaria e soltaria o componente de trabalho em segundo plano na superfície de design de um formulário - algo que não pode ser feito com
async
/await
eTask
... ou seja, você venceu ' t crie manualmente o objeto, defina as propriedades e os manipuladores de eventos. você só preencher o corpo dosDoWork
,RunWorkerCompleted
eProgressChanged
manipuladores de eventos.Se você "converteu" isso em assíncrono / espera, faria algo como:
Sem a capacidade de arrastar um componente para uma superfície do Designer, cabe ao leitor decidir qual é "melhor". Mas, para mim, essa é a comparação entre
await
eBackgroundWorker
, não se você pode aguardar métodos internos comoStream.ReadAsync
. por exemplo, se você estiver usandoBackgroundWorker
como pretendido, pode ser difícil converter para usarawait
.Outras opiniões: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html
fonte
var t1 = webReq.GetResponseAsync(); var t2 = webReq2.GetResponseAsync(); await t1; await t2;
. O que aguardaria duas operações paralelas. Await é muito melhor para assíncrona, mas tarefas seqüenciais, IMO ...await Task.WhenAny(t1, t2)
fazer algo quando a tarefa fosse concluída primeiro. Você provavelmente desejaria um loop para garantir que a outra tarefa também seja concluída. Geralmente, você deseja saber quando uma tarefa específica é concluída, o que o leva a escreverawait
s sequenciais .Esta é uma boa introdução: http://msdn.microsoft.com/en-us/library/hh191443.aspx A seção Threads é exatamente o que você está procurando:
fonte
BackgroundWorker é explicitamente rotulado como obsoleto no .NET 4.5:
O artigo do MSDN "Programação assíncrona com Async e Await (C # e Visual Basic)" informa:
ATUALIZAR
"para operações com IO porque o código é mais simples e você não precisa se proteger contra as condições da corrida" Que condições da corrida podem ocorrer, você poderia dar um exemplo? "
Esta pergunta deveria ter sido colocada como um post separado.
A Wikipedia tem uma boa explicação das condições de corrida . A parte necessária é multithreading e do mesmo artigo do MSDN Programação assíncrona com Async e Await (C # e Visual Basic) :
Ou seja, "As palavras-chave assíncronas e aguardam não causam a criação de threads adicionais".
Tanto quanto me lembro de minhas próprias tentativas, quando eu estava estudando este artigo, há um ano, se você executou e brincou com um exemplo de código do mesmo artigo, poderá encontrar situações nas versões não assíncronas (você pode tentar converter bloqueie indefinidamente!
Além disso, para exemplos concretos, você pode pesquisar neste site. Aqui estão alguns exemplos:
fonte