Question

J'utilise un NetworkStream & TcpClient pour recevoir de manière asynchrone des données en utilisant BeginRead. Je dois appliquer une temporisation à cette opération, de sorte qu'après un certain laps de temps, la lecture sera annulée.

Pour autant que je suis en mesure de dire, ce ne sont pas pris en charge sur NetworkStream ou TcpClient - il y a une propriété ReceiveTimeout, mais cela semble ne s'applique à la synchrone équivalent - « Lire »

.

Même le sous-jacent classe Socket ne semble pas les délais d'attente de support dans sa méthode BeginReceive.

Je l'ai recherché sur cette question et la résolution que suggéré que je l'ai vu est de mettre en place un autre thread d'arrière-plan pour annuler l'opération si elle ne se termine pas dans le délai imparti. Cela semble être un horrible hack. Certes, il y a une façon meilleure?

Était-ce utile?

La solution

Il est la seule façon de le faire, parce que quand vous utilisez une opération asynchrone, le fil qui a initié l'opération est de faire autre chose. Le délai d'attente est disponible avec la version synchrone car le thread d'exécution est bloquée jusqu'à ce que le finalise d'opération de lecture.

Si vous devez utiliser un fil d'arrière-plan pour annuler l'opération, cependant, il n'y aurait pas beaucoup de point de continuer à utiliser l'asynchrone Begin / méthodes de fin. Si vous allez spin off un fil d'arrière-plan, juste effectuer une opération synchrone lecture à partir du fil de fond, et vous pouvez utiliser le ReceiveTimeout.

Autres conseils

Attendez sur ManualResetEvent avec une valeur de délai d'attente signal lorsque votre tâche est terminée. S'il arrive à expiration avant qu'il ne soit signalé, alors vous savez que l'opération asynchrone jamais terminée.

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);

Dans le rappel BeginReceive, utilisez

private void ReceiveCallBack(IAsyncResult ar)
{
    /** Use ar to check if receive is correct and complete */
    receiveDone.Set();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top