C#在网络流上设置WriteTimeOut / ReadTimeout没有什么区别



我在xamarin.forms应用程序中有以下方法代码

using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
{
    byte[] messageBytes = PrepareMessageBytes();
    //
    // Setting these seam to have no effect
    //
    stream.WriteTimeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
    stream.ReadTimeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
    //
    // I have set read and write timeouts above but when 
    // hitting this line, app hangs indefinitely?  
    // I would expect that after 10 seconds, a IOException
    // will be thrown
    await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
    stream.Flush();
    byte[] buffer = new byte[1024];
    StringBuilder builder = new StringBuilder();
    int bytesRead = 0;
    while (stream.DataAvailable)
    {
        bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
        builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
    }
    string msg = receivedMessage.ToString();
} 

上面,我将写入和阅读超时设置为10秒。我知道我的代码挂在:

的电话上

等待stream.writeasync(...)

,但我希望10秒后,将会抛出一个ioException。基于MS文档,ASYNC写入/读取并非如此。

如何设置呼叫writeasync/readasync方法的超时?

更新 - 基于Stephen的评论

的第二次尝试

根据Stephen的评论,我更新了代码,并将其包装到try..catch中以处理操作CanceLledException。,但这比以前引起的问题更多,并且该应用程序仍然大部分时间

try
{
    using (TcpClient client = new TcpClient(ip, port))
    using (NetworkStream stream = client.GetStream())
    using (var writeCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
    {
        byte[] messageBytes = PrepareMessageBytes();
        await stream.WriteAsync(messageBytes, 0, messageBytes.Length, writeCts.Token);
        await stream.FlushAsync();
        byte[] buffer = new byte[1024];
        StringBuilder builder = new StringBuilder();
        int bytesRead = 0;
        while (stream.DataAvailable)
        {
            using (var readCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
                bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, readCts.Token);
            builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
        }
        string msg = receivedMessage.ToString();
    }
catch (OperationCancelledException ex)
{
    Debug.WriteLine(ex.Message);
}

如何设置呼叫writeasync/readasync方法的超时?

您使用 CancellationToken参数的过载:

using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
using (var writeCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
{
    byte[] messageBytes = PrepareMessageBytes();
    await stream.WriteAsync(messageBytes, 0, messageBytes.Length, writeCts.Token);
    await stream.FlushAsync();
    byte[] buffer = new byte[1024];
    StringBuilder builder = new StringBuilder();
    int bytesRead = 0;
    while (stream.DataAvailable)
    {
        using (var readCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
            bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, readCts.Token);
        builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
    }
    string msg = receivedMessage.ToString();
}

我希望在10秒钟后,将抛出一个ioException。

使用取消令牌时,请期待OperationCanceledException。从技术上讲,取消令牌可用于各种取消方案 - 代码决定它不再需要完成操作,用户手动取消了操作,或者有超时。 OperationCanceledException是通用异常类型,意思是"取消"。

相关内容

  • 没有找到相关文章

最新更新