10

タイムアウトによってTcpClient ReadAsync操作をキャンセルし、.NET 4.5でこのタイムアウトイベントをキャッチする適切な方法は何ですか?

TcpClient.ReadTimeout は同期読み取り専用に適用されるようです。

更新:
ここで説明されているアプローチを適用しようとしました 非同期操作のキャンセル

var buffer = new byte[4096];
CancellationTokenSource cts = new CancellationTokenSource(5000);
int amountRead = await tcpClientStream.ReadAsync(buffer, 0, 4096, cts.Token);

ただし、タイムアウトによってキャンセルされることはありません。何か問題がありますか?

4

4 に答える 4

12

だから私はそれが長い間あったことを知っていますが、Googleはまだ私をここに追いやっています。答えとしてマークされたものはありません

私にとっては、余分なタイムアウトを取るメソッド ReadAsync を追加する拡張機能を作成するように解決します

public static async Task<int> ReadAsync(this NetworkStream stream, byte[] buffer, int offset, int count, int TimeOut)
{
    var ReciveCount = 0;
    var receiveTask = Task.Run(async () => { ReciveCount = await stream.ReadAsync(buffer, offset, count); });
    var isReceived = await Task.WhenAny(receiveTask, Task.Delay(TimeOut)) == receiveTask;
    if (!isReceived) return -1;
    return ReciveCount;
}

したがって、-1 が返された場合は、読み取りがタイムアウトしたことを意味します

于 2016-12-16T23:16:40.740 に答える
-1

編集:OK、それはスレッドをロックします。しかし、多くのアプリケーションにとって、これはまだ単純な解決策だと思います。

OK、これは古いスレッドですが、私自身の解決策を共有したいと思いました。

例を使用する代わりに

int length = await stream.Read(buffer, 0, 2, cancellationToken);

単に使用する

int length = 0;
await Task.Run(() => { length = stream.Read(buffer, 0, 2); });

これは stream.ReadTimeout を尊重します。

于 2021-10-02T19:48:22.187 に答える