Tudo bem. Tudo o que você está fazendo é resolver a tarefa antes de passar o parâmetro. É exatamente o mesmo que var x = aguardar GetDataAsync; var results = MapResults (x); Não faz diferença, e geralmente se resume às diretrizes de codificação que você deseja implementar por si mesmo
Heinrich
1
Legibilidade do código. É literalmente a mesma coisa quevar result = await GetDataAsync(); var map = MapResults(result)
Zer0
@ Zer0 qual é legível, aquele com resultados var? ou a única linha?
Drew Aguirre
@ Heinrich sim, eu concordo com você. Só me preocupo em aplicar algumas práticas ruins no meu código para fazer uma única linha.
Drew Aguirre
3
@DrewAguirre: esses dois últimos são completamente diferentes e VOCÊ NÃO DEVE FAZER O MAIS TARDE . Espero que esteja claro. O primeiro faz uma espera assíncrona; o último faz uma espera síncrona em um fluxo de trabalho assíncrono. Agora, suponha que o fluxo de trabalho assíncrono tenha agendado trabalho no futuro no encadeamento atual . Uma espera síncrona significa "suspender esse encadeamento até que o trabalho que esse encadeamento realizará no futuro seja concluído" e, obviamente, que durma para sempre.
Eric Lippert
Respostas:
28
ATUALIZAÇÃO: Esta questão foi o assunto do meu blog em março de 2020 . Veja-o para mais discussões sobre esta questão. Obrigado pela pergunta interessante!
Vou assumir aqui que você pretendia que fosse uma chamada de função como o único membro da lista de argumentos.
Como outros observaram, não há diferença entre
x = M(awaitFAsync());
e
var f =awaitFAsync();
x = M(f);
E isso é o mesmo que
var ftask =FAsync();
x = M(await ftask)
Portanto, não importa como você escreve, correto?
Pense nisso.
Nesse cenário específico , todos os três fluxos de trabalho são iguais. Mas há uma diferença potencial aqui se apenas variarmos ligeiramente o cenário. Considerar:
x = M(awaitFAsync(),awaitGAsync());
É o mesmo que
var f =awaitFAsync();var g =awaitGAsync();
x = M(f, g);
e o que sabemos sobre esse fluxo de trabalho? A tarefa do GAsync não é iniciada até que a tarefa do FAsync seja concluída! Mas parece que há uma oportunidade de ter duas tarefas acontecendo ao mesmo tempo aqui, que podem usar o encadeamento atual com mais eficiência! Provavelmente, o fluxo de trabalho seria melhor escrito como:
var ftask =FAsync();var gtask =GAsync();
x = M(await ftask,await gtask);
Agora, as tarefas FAsync e GAsync são iniciadas e não chamamos M até que ambas terminem.
Meu conselho é pensar cuidadosamente sobre onde você espera. Lembre-se de que uma espera é um ponto em um fluxo de trabalho assíncrono em que o fluxo de trabalho é interrompido de forma assíncrona até que uma condição prévia da continuação seja atendida . Se você pode adiar a espera de uma tarefa até que ela seja realmente uma pré-condição, poderá conseguir uma vitória no desempenho.
É claro que é bom estar ciente do suporte multithreading subjacente das tarefas que você está aguardando. Você não pode aguardar simultaneamente em duas tarefas que geram dados do banco de dados e usam o mesmo SqlConnectionou DbContextpor exemplo.
Sebazzz 10/03
1
Uau! Estou impressionado .. desculpe, estive ocupado e não respondi na sua resposta .. Marquei esta como a resposta .. a explicação é muito clara .. e sim, aprendi muito apenas lendo as poucas linhas que você escreveu .. e eu também li o seu blog .. bom trabalho! e continue assim ..
Drew Aguirre
5
Não há diferença de tempo de execução entre;
var results =MapResults(awaitGetDataAsync())
e
var tmp =awaitGetDataAsync();var results =MapResults(tmp)
Sim, não há diferença. o que estou pensando, há algum problema técnico para fazer isso? ou é mais limpo usar a variável "tmp"? Não vejo nenhuma desvantagem em usar a primeira linha. mesmo que haja uma exceção que será lançada em GetDataAsync ().
Drew Aguirre
É uma prática ruim fazer a primeira linha?
Drew Aguirre
Prefiro o segundo padrão, 1) mais legível, 2) posso massagear o código antes de passar para os resultados.
Harris Yer
Observe que o OP usou a variável ( GetDataAsync) e não a chamada de método. Dependendo de onde isso Task GetDataAsync = CallSomeAsync()foi inicializado, pode haver diferenças significativas, pois a tarefa já estará em execução quando o tempo MapResults(await GetDataAsync)for chamado. Veja a resposta de Eric para mais detalhes.
Alexei Levenkov
Sim, já que não havia contexto suficiente, presumi que fosse um erro de digitação ...
var result = await GetDataAsync(); var map = MapResults(result)
Respostas:
ATUALIZAÇÃO: Esta questão foi o assunto do meu blog em março de 2020 . Veja-o para mais discussões sobre esta questão. Obrigado pela pergunta interessante!
Vou assumir aqui que você pretendia que fosse uma chamada de função como o único membro da lista de argumentos.
Como outros observaram, não há diferença entre
e
E isso é o mesmo que
Portanto, não importa como você escreve, correto?
Pense nisso.
Nesse cenário específico , todos os três fluxos de trabalho são iguais. Mas há uma diferença potencial aqui se apenas variarmos ligeiramente o cenário. Considerar:
É o mesmo que
e o que sabemos sobre esse fluxo de trabalho? A tarefa do GAsync não é iniciada até que a tarefa do FAsync seja concluída! Mas parece que há uma oportunidade de ter duas tarefas acontecendo ao mesmo tempo aqui, que podem usar o encadeamento atual com mais eficiência! Provavelmente, o fluxo de trabalho seria melhor escrito como:
Agora, as tarefas FAsync e GAsync são iniciadas e não chamamos M até que ambas terminem.
Meu conselho é pensar cuidadosamente sobre onde você espera. Lembre-se de que uma espera é um ponto em um fluxo de trabalho assíncrono em que o fluxo de trabalho é interrompido de forma assíncrona até que uma condição prévia da continuação seja atendida . Se você pode adiar a espera de uma tarefa até que ela seja realmente uma pré-condição, poderá conseguir uma vitória no desempenho.
fonte
SqlConnection
ouDbContext
por exemplo.Não há diferença de tempo de execução entre;
e
fonte
GetDataAsync
) e não a chamada de método. Dependendo de onde issoTask GetDataAsync = CallSomeAsync()
foi inicializado, pode haver diferenças significativas, pois a tarefa já estará em execução quando o tempoMapResults(await GetDataAsync)
for chamado. Veja a resposta de Eric para mais detalhes.