Como obter Thread.Sleep aguardável?

139

Estou escrevendo um aplicativo vinculado à rede com base no paradigma de espera / suspensão.

Às vezes, erros de conexão acontecem e, na minha experiência, vale a pena esperar um pouco e tentar novamente a operação novamente.

O problema é que, se eu usar o Thread.Sleep ou outra operação de bloqueio semelhante em wait / async, ele bloqueia toda a atividade no thread do chamador.

Com o que devo substituir o Thread.Sleep (10000) para obter o mesmo efeito que

await Thread.SleepAsync(10000)

?

ATUALIZAR

Prefiro uma resposta que faça isso sem criar nenhum tópico adicional

Arsen Zahray
fonte

Respostas:

323

As outras respostas que sugerem o início de um novo tópico são uma péssima idéia - não é necessário fazer isso. Parte do ponto de async/ awaité reduzir o número de threads que seu aplicativo precisa.

Em vez disso, você deve usar o Task.Delayque não requer um novo encadeamento e foi projetado precisamente para esta finalidade:

// Execution of the async method will continue one second later, but without
// blocking.
await Task.Delay(1000);
Jon Skeet
fonte
Eu ainda estou lidando com o material a4.5. Onde está o ramo de execução no código após essa declaração? A parte que não dorme / bloqueia o executa ou o 'thread' que aguarda? A execução principal sem bloqueio apenas deixa o bloco a seguir (também conhecido como retorno)?
Kenny
1
sim. Este é exatamente o que eu preciso
Arsen Zahray
1
@kenny: Você pode achar minha asyncintrodução útil. Quando o esperado retornado por Task.Delayé awaited, uma vez que não está completo, o método atual retorna uma tarefa incompleta. Mais tarde, quando a Delayconclusão (fora de um cronômetro, não de um encadeamento), o restante do método está agendado para execução. A continuação é executada em um "contexto" que pode retornar ao mesmo thread original - detalhes no meu blog.
Stephen Cleary
@StephenCleary obrigado por isso. Então, estou certo ao dizer que o código após aguardar é 'agendado' para execução e o thread de chamada retorna?
Kenny
2
Sim, o encadeamento de chamada retorna (imediatamente) e o código após o awaitagendamento (eventualmente).
precisa