首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#在网络流上设置WriteTimeout / ReadTimeout没有区别吗?

C#在网络流上设置WriteTimeout / ReadTimeout没有区别吗?
EN

Stack Overflow用户
提问于 2019-02-21 20:58:11
回答 1查看 1.7K关注 0票数 0

我的Xamarin.Forms应用程序中有以下方法代码

代码语言:javascript
运行
复制
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文档,异步写入/读取不是这种情况。

如何设置调用WriteAsync / ReadAsync方法的超时?

更新--基于评论的第二次尝试

根据Stephen的评论,我更新了代码并将其封装到try..catch中以处理OperationCancelledException。,但这造成了比以前更多的问题,应用程序大部分时间仍将挂起

代码语言:javascript
运行
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2019-02-22 14:35:03

如何设置调用WriteAsync / ReadAsync方法的超时?

使用接受CancellationToken参数的重载:

代码语言:javascript
运行
复制
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是泛型异常类型,意思是“取消”。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54816114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档