Async / Await vs Threads


100

No .Net 4.5, a Microsoft adicionou o novo Async/Awaitrecurso para simplificar a codificação assíncrona. No entanto, eu me pergunto

  1. Pode Async/Awaitsubstituir completamente a velha maneira de usar Threads?
  2. É Async/Awaitcapaz de fazer tudo o que a Threadpode fazer de forma assíncrona?
  3. Async/AwaitSó pode ser usado com alguns métodos, como WebClient.DownloadStringAsyncou posso converter qualquer método síncrono para torná-lo usado Async/Awaite não para bloquear o thread principal?

2
Threads e Async / Await são recursos não relacionados. Você pode combiná-los, mas não precisa.
dtb

2
Eu pensei que Async / Await está fazendo a mesma coisa que new Thread(() => {Some Work}).Start();está fazendo?! não é?
Roman Ratskey

2
Não. Sua suposição não está correta. Você pode estar pensando em Task.Run (TPL), que geralmente é combinado com Async / Await, mas também não está relacionado e não precisa ser usado com ele.
dtb

4
@dtb: Então, quando usar Async / Await e quando usar Threads? Estou realmente confuso sobre a diferença entre Task.Run, Thread.Start, Async / Await. Se você pudesse me fornecer uma boa explicação que me faça entender as diferenças entre eles, eu ficaria muito grato
Roman Ratskey

2
Async / await não cria ou usa threads de qualquer outra forma.
wRAR

Respostas:


78

ele pode substituir completamente a velha maneira de usar Threads?

Não. Um tópico pode fazer muitas coisas mais úteis. O Await foi projetado especificamente para lidar com algo que leva tempo, normalmente uma solicitação de E / S. O que tradicionalmente era feito com um retorno de chamada quando a solicitação de E / S era concluída. Escrever código que depende desses callbacks é bastante difícil, o await o simplifica muito.

capaz de fazer tudo o que um Thread pode fazer de forma assíncrona?

Aproximadamente. O Await apenas se encarrega de lidar com o atraso, caso contrário, ele não faz nada que um thread faz. A expressão await , o que está à direita da palavra-chave await, é o que executa o trabalho. O ideal é que ele não use nenhum thread, ele posta uma solicitação de driver e, uma vez que o driver conclui a transferência de dados, ele gera um retorno de chamada de notificação de conclusão. A rede é de longe o uso mais comum, latências de centenas de milissegundos são comuns e um efeito colateral inevitável da transferência de serviços do desktop ou de uma LAN para "a nuvem". Usar esses serviços de forma síncrona faria com que a IU parasse de responder.

só pode ser usado com alguns métodos como WebClient.DownloadStringAsync

Não. Você pode usá-lo com qualquer método que retorne uma Tarefa. Os métodos XxxxAsync () são apenas aqueles pré-cozinhados na estrutura .NET para operações comuns que levam tempo. Como baixar dados de um servidor web.


4
No aspecto do C # moderno, qual é a melhor abordagem para obter Callbacks assíncronos em APIs externas?
bonCodigo

5
Abordado no último parágrafo, use uma Tarefa.
Hans Passant

Eu esperaria algo que um thread pode fazer e que não pode ser feito por meio de programação assíncrona, como exemplo.
Saeed Neamati

1
Você poderia expandir em "Um tópico pode fazer muitas coisas mais úteis."? Seria útil entender os recursos para os quais os encadeamentos são asyncinadequados.
Benjohn

1
Vale a pena mencionar await Task.Runpara trabalho vinculado à CPU. Se bem entendi, isso às vezes realiza o que se criaria um thread ou um trabalhador de segundo plano para fazer.
Toolmaker Steve

15

A declaração oficial sobre isso. Embora você deva entender as diferenças entre threads e programação assíncrona antes de substituir cegamente uma coisa por outra.


É como o primeiro recurso que li sobre Threads e Async / Await que é claro e conciso.
Arman Bimatov

2
Esta resposta contém apenas um link para a documentação. Como o link pode ficar desatualizado, a resposta também pode ficar desatualizada - ou pior ainda - completamente inútil. Encorajamos os usuários do Stack a postar as partes relevantes dos links diretamente em suas perguntas.
HimBromBeere

1
Infelizmente, a declaração oficial não explica quando fazer await Task.Run. Há uma breve menção de Task.Run, mas não está claro. O ponto principal é que awaitpor si só não fará uma tarefa vinculada à CPU ser executada em paralelo, portanto, esse trabalho deve ser feito via await Task.Run.
Toolmaker Steve

1

Eu penso sobre isso dessa forma (e acho que a Microsoft também se você olhar em https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ) #threads )

Async / await é uma maneira rápida de executar algum código no thread principal do aplicativo com a vantagem de que o código pode se suspender quando não tem trabalho a fazer e retornar o foco para o thread principal, "despertar" no thread principal quando houver é um resultado a ser obtido e, em seguida, repassar o processamento para - você adivinhou - o thread principal. Pense nisso como uma instrução GOTO baseada em eventos no Basic que pode passar o controle para frente e para trás para uma linha de execução específica.

Em contraste, um thread é um fluxo separado de execução que pode ser executado com suas próprias variáveis, etc. onde - dado hardware suficiente - a execução ocorre em paralelo ao thread principal.

Se você tiver um aplicativo GUI que vai baixar um único arquivo e, em seguida, fazer algo com esse arquivo quando ele for baixado - eu implementaria isso usando um método async / await.

No entanto, se sua GUI precisar baixar 5000 arquivos - eu criaria um thread de download de arquivo para lidar com isso, já que o thread da GUI principal pode congelar enquanto a execução é transferida para lidar com o download dos arquivos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.