Pergunta

Estou usando um NetworkStream & TCPClient para receber dados de forma assíncrona usando o BEGINRAD. Preciso aplicar um tempo limite a esta operação, de modo que, após uma quantidade especificada de tempo, a leitura será abortada.

Até onde sou capaz de dizer, isso não é suportado no NetworkStream ou no TCPClient - existe uma propriedade RECEVETimeout, mas isso parece se aplicar apenas ao equivalente síncrono - 'Read'.

Mesmo a classe de soquete subjacente não parece suportar tempo limite em seu método iniciante.

Eu pesquisei sobre esse problema e a única resolução sugerida que vi é configurar outro thread de segundo plano para cancelar a operação se não concluir dentro do período de tempo limite. Parece um hack horrível. Certamente há uma maneira melhor?

Foi útil?

Solução

É a única maneira de fazê -lo, porque quando você está usando uma operação assíncrona, o encadeamento que iniciou a operação está fazendo outra coisa. O tempo limite está disponível com a versão síncrona porque o thread de execução é bloqueado até que a operação de leitura seja concluída.

Se você precisar usar um encadeamento de segundo plano para cancelar a operação, não haveria muito sentido em continuar usando os métodos de início/final assíncronos. Se você quiser girar um encadeamento de segundo plano, basta executar uma operação de leitura síncrona a partir do encadeamento em segundo plano e, em seguida, poderá usar o RECEVETIMEOUT.

Outras dicas

Espere ManualResetevent com algum valor de tempo limite para sinalizar quando sua tarefa é concluída. Se ele se destacar antes de ser sinalizado, você sabe que a operação assíncrona nunca foi concluída.

private ManualResetEvent receiveDone = new ManualResetEvent(false);

receiveDone.Reset();
socket.BeginReceive(...);
if(!receiveDone.WaitOne(new TimeSpan(0, 0, 0, 30))) //wait for 30 sec.
    throw new SocketException((int)SocketError.TimedOut);

Dentro de retorno de chamada para iniciantes, use

private void ReceiveCallBack(IAsyncResult ar)
{
    /** Use ar to check if receive is correct and complete */
    receiveDone.Set();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top