Eu posso estar perdendo alguma coisa
Tu es.
qual é a diferença entre doing Task.Wait
e await task
?
Você pede seu almoço no garçom do restaurante. Um momento depois de fazer seu pedido, um amigo entra e senta-se ao seu lado e inicia uma conversa. Agora você tem duas opções. Você pode ignorar seu amigo até que a tarefa seja concluída - você pode esperar até que sua sopa chegue e não fazer mais nada enquanto estiver esperando. Ou você pode responder ao seu amigo e, quando ele parar de falar, o garçom lhe trará sua sopa.
Task.Wait
bloqueia até que a tarefa seja concluída - você ignora seu amigo até que a tarefa seja concluída. await
mantém o processamento de mensagens na fila de mensagens e, quando a tarefa é concluída, enfileira uma mensagem que diz "retome de onde você parou depois que a espera". Você fala com seu amigo e, quando há uma pausa na conversa, a sopa chega.
Task
que leva 10 ms realmente executasse 10 horasTask
no seu encadeamento, bloqueando você por 10 horas inteiras?Para demonstrar a resposta de Eric, aqui está um código:
fonte
//If you press Button2 now you won't see anything in the console until this task is complete and then the label will be updated!
" é enganosa. Ao pressionar o botão com ot.Wait();
manipulador de eventos click no botãoButtonClick()
, não é possível pressionar nada e ver algo no console e atualização do rótulo "até que esta tarefa seja concluída", pois a GUI está congelada e não responde, ou seja, cliques ou interações com a GUI estão sendo PERDIDO até a conclusão da tarefa de esperat.Wait
bloco principal será bloqueado até que a tarefa seja concluída".Este exemplo demonstra a diferença muito claramente. Com assíncrono / espera, o segmento de chamada não será bloqueado e continuará executando.
Saída DoAsTask:
Saída DoAsAsync:
Atualização: Exemplo aprimorado, mostrando o ID do encadeamento na saída.
fonte
Wait () fará com que o código potencialmente assíncrono seja executado de maneira sincronizada. aguardar não.
Por exemplo, você tem um aplicativo Web asp.net. O usuário A chama o terminal / getUser / 1. O pool de aplicativos asp.net selecionará um thread do pool de threads (Thread1) e, esse thread fará uma chamada http. Se você esperar (), esse encadeamento será bloqueado até que a chamada http seja resolvida. Enquanto estiver aguardando, se o UsuárioB chamar / getUser / 2, o pool de aplicativos precisará atender outro encadeamento (Thread2) para fazer a chamada http novamente. Você acabou de criar (bem, buscado no pool de aplicativos, na verdade) outro encadeamento sem motivo, porque você não pode usar o Thread1, pois foi bloqueado por Wait ().
Se você usar aguardar no Thread1, o SyncContext gerenciará a sincronização entre o Thread1 e a chamada http. Simplesmente, ele será notificado assim que a chamada http for concluída. Enquanto isso, se o UsuárioB chamar / getUser / 2, você usará o Thread1 novamente para fazer uma chamada http, porque foi liberada uma vez que a espera foi atingida. Em seguida, outro pedido pode usá-lo, ainda mais. Depois que a chamada http é concluída (usuário1 ou usuário2), o Thread1 pode obter o resultado e retornar ao chamador (cliente). O Thread1 foi usado para várias tarefas.
fonte
Neste exemplo, não muito, praticamente. Se você estiver aguardando uma tarefa que retorne em um encadeamento diferente (como uma chamada WCF) ou renuncie ao controle do sistema operacional (como IO do arquivo), aguardar utilizará menos recursos do sistema, não bloqueando um encadeamento.
fonte
No exemplo acima, você pode usar "TaskCreationOptions.HideScheduler" e modificar bastante o método "DoAsTask". O método em si não é assíncrono, como acontece com "DoAsAsync" porque retorna um valor de "Tarefa" e é marcado como "assíncrono", fazendo várias combinações. É assim que me dá exatamente o mesmo que usar "async / waitit" :
fonte