带有取消令牌的 NetworkStream.ReadAsync 永远不会取消

2023-11-21

证据在这里。
知道这段代码有什么问题吗?

    [TestMethod]
    public void TestTest()
    {
        var tcp = new TcpClient() { ReceiveTimeout = 5000, SendTimeout = 20000 };
        tcp.Connect(IPAddress.Parse("176.31.100.115"), 25);
        bool ok = Read(tcp.GetStream()).Wait(30000);
        Assert.IsTrue(ok);
    }

    async Task Read(NetworkStream stream)
    {
        using (var cancellationTokenSource = new CancellationTokenSource(5000))
        {
            int receivedCount;
            try
            {
                var buffer = new byte[1000];
                receivedCount = await stream.ReadAsync(buffer, 0, 1000, cancellationTokenSource.Token);
            }
            catch (TimeoutException e)
            {
                receivedCount = -1;
            }
        }
    }

我终于找到了解决方法。使用 Task.WaitAny 将异步调用与延迟任务 (Task.Delay) 结合起来。当 io 任务之前的延迟过去时,关闭流。这将迫使任务停止。您应该正确处理 io 任务上的异步异常。并且您应该为延迟任务和 io 任务添加一个延续任务。

它也适用于 TCP 连接。关闭另一个线程中的连接(您可以认为它是延迟任务线程)会强制所有使用/等待此连接的异步任务停止。

--EDIT--

@vtortola 建议的另一个更干净的解决方案:使用取消令牌来注册对 Stream.Close 的调用:

async ValueTask Read(NetworkStream stream, TimeSpan timeout = default)
{
    if(timeout == default(TimeSpan))
      timeout = TimeSpan.FromSeconds(5);

    using var cts = new CancellationTokenSource(timeout); //C# 8 syntax
    using(cts.Token.Register(() => stream.Close()))
    {
       int receivedCount;
       try
       {
           var buffer = new byte[30000];
           receivedCount = await stream.ReadAsync(buffer, 0, 30000, tcs.Token).ConfigureAwait(false);
       }
       catch (TimeoutException)
       {
           receivedCount = -1;
       }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有取消令牌的 NetworkStream.ReadAsync 永远不会取消 的相关文章

  • 使用 F5 时,finally 似乎没有在 C# 控制台应用程序中执行

    int i 0 try int j 10 i catch IOException e finally Console WriteLine In finally Console ReadLine 在VS2008中按F5时 finally块似乎
  • 如何查找局域网中所有主机上正在运行的程序的所有实例?

    出于实际目的 SqlDataSourceEnumerator 的作用是查找在 LAN 上的各个 PC 上运行的 SQL Server 的所有实例 是否有等效的方法可以查找任意应用程序的运行实例 编辑 好的 所以这只有效 因为这些应用程序有预
  • C# .Net Serial DataReceived 事件响应对于高速数据来说太慢

    我已经设置了一个 SerialDataReceivedEventHandler 并在 VS2008 Express 中使用基于表单的程序 我的串口设置如下 115200 8N1 Dtr 和 Rts 已启用 接收字节阈值 1 我有一个通过蓝牙
  • System.Drawing.Image.Save 抛出ExternalException:GDI 中发生一般错误

    我有一个函数 它需要一个位图 复制它的一部分并将其保存为 8bpp tiff 结果图像的文件名是唯一的并且文件不存在 程序有权写入目标文件夹 void CropImage Bitmap map Bitmap croped new Bitma
  • 分层架构中的异常处理

    我们正在分层设计中重构 当然还有重新设计 我们的服务 我们有服务操作层 BLL 网络抽象层 gt 处理网络代理 数据抽象层 但我们对我们的异常处理策略有点困惑 我们不想向外界透露太多 BLL 的信息 从其他层到bll就可以了 我们不想让 t
  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • MySql 最后插入 ID,连接器 .net

    我正在使用 MySql Connector net 我需要获取最后一个查询生成的插入 id 现在 我假设返回值是MySqlHelper ExecuteNonQuery应该是最后一个插入id 但它只返回1 我正在使用的代码是 int inse
  • 如何将智能感知添加到我的应用程序中?

    我们的一款产品拥有一种专有的宏语言 通过我们的 Windows 软件进行编辑 我想添加智能感知 但我不知道如何去做 至少不完全重新发明轮子 是否有任何示例代码或第 3 方包至少可以让我开始 它不一定是免费的 该应用程序使用 NET 用 C
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 托管 .NET 代码中的“访问冲突写入位置...”

    我收到以下异常 MqSearch exe 中 0x000007FE21AFE593 mscorlib ni dll 处出现未处理的异常 0xC0000005 写入位置 0x00000006609476FD 时出现访问冲突 代码是完全托管的
  • 如何让 LinqToSql 将“索引提示”传递给 sql server?

    由于我们不能相信我们的客户会更新 sql server 中的索引统计信息等 因此我们过去不得不使用索引提示 http www sql server performance com tips hints general p1 aspx 由于我
  • 如何在 VS2017/2015 中打开 .xproj 文件

    我有一个带有扩展名的 NET core 项目 xproj 当我在VS 2017中打开项目时 项目文件 xproj migrated to csproj 如何打开 xproj 文件 Visual Studio 2017 2015 我需要安装任
  • 同一服务器上的多个.NET版本

    所以我一直都知道在一台计算机 客户端或服务器 上运行多个版本的 NET 框架是可以的 这个问题 https stackoverflow com questions 407306 running many versions of net on
  • C# - 方法必须有返回类型

    我在调用 C 中的方法时遇到问题 不断收到消息 方法 计算 必须有返回类型 using System Diagnostics namespace WindowsFormsApplication1 public partial class F
  • CompileAssemblyFromDom 抛出访问被拒绝异常

    代码 using var codeProvider new CSharpCodeProvider var compilerParameter new CompilerParameters assemblies assemblyName fa
  • “你好世界!!”在 .NET 4 中生成 3500 个页面错误

    我正在运行 Windows Vista 和 Visual Studio 2010 使用 NET 4 2 GB RAM 和大约 800 MB 可用空间 我创建了一个 Windows 窗体应用程序 但没有向其中添加任何代码 只需在发布模式下编译
  • 如何等待远程 .NET 调试器连接

    今天我遇到了一个问题 我需要远程调试程序 该程序是从另一个系统启动的 所以我真的没有机会在命令行上与它交互 不过我可以很容易地改变它的来源 我需要做的是让程序正常启动 然后等待我用调试器附加到它 我想不出一个让我快乐的方法 我确实发现了这个
  • .NET“默认行终止符”?

    有什么方法可以弄清楚 NET 使用什么作为其 默认行终止符 例如 StringBuilder AppendLine String 的文档表示 附加指定字符串的副本 后跟默认行终止符 NET 中的几个与文本相关的类引用相同的概念 有什么方法可
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 引用的程序集自动由 Visual Studio 替换

    我有 2 个项目 一个可移植类库和一个常规单元测试项目 在可移植类库中 我使用 NuGet 来引用 Microsoft BCL 可移植包 它附带 2 个程序集 System Threading Tasks dll and System Ru

随机推荐

  • Three.js 截图

    我需要制作网站的屏幕截图 我尝试使用 html2canvas 和所有它的工作 但问题是我正在使用 THREE WebGLRenderer 和 THREE CSS3DRenderer 用于 webgl 中的 html 所以当我制作屏幕截图时
  • 如何为相同大小分区的 Spark RDD 定义自定义分区器,其中每个分区具有相同数量的元素?

    我是 Spark 新手 我有一个大型元素数据集 RDD 我想将其划分为两个大小完全相同的分区 以保持元素的顺序 我尝试使用RangePartitioner like var data partitionedFile partitionBy
  • 序列化有时是数组的 Json 属性[重复]

    这个问题在这里已经有答案了 有没有什么方法可以在一次操作中序列化从十进制到十进制 的 Json 对象属性 在我的 Json 产品提要中 特价商品表示为数组 正常价格 促销价格 普通商品只是价格 就像这样 product umbrella p
  • C++ 未处理的异常

    如果发生未处理的异常 C 是否提供了一种 显示 可视化内容的方法 我想做的是做一些像assert unhandled exception msg 如果它确实发生 如下面的示例所示 include
  • Android 未解决的主机异常

    我尝试使用以下方法从 Android 应用程序调用 RESTful Web 服务 HttpHost target new HttpHost http ServiceWrapper SERVER HOST ServiceWrapper SER
  • Git 哈希值是如何计算的?

    我试图了解 Git 如何计算 refs 的哈希值 git ls remote https github com git git 29932f3915935d773dc8d52c292cadd81c81071d refs tags v2 4
  • 如何在 Qt 中通过以太网播放流媒体音频?

    我的目标是通过 LAN 网络无延迟或最少延迟地传输 wav 文件 我们还按部分读取服务器计算机上的文件 均为 320 字节 之后我们通过 UDP 发送数据包并将接收写入 jitter buffer 中 抖动缓冲区的大小为 10 为了获得清晰
  • 部署带有嵌入式sqlite的winform应用程序

    我正在部署一个使用 vs 2008 0n XP sp3 构建的 winform 应用程序 我创建了一个带有空架构的数据库 将其放入项目的根文件夹和我选择的属性中Build Action 嵌入式资源 and Copy to Output di
  • iPhone:安装 SSL 连接证书

    我希望我的应用程序在设备上安装 SSL 证书 使其能够访问我的 https 网站 任何建议将不胜感激 谢谢 我发现最好的方法是执行以下操作 1 使用桌面浏览器将证书保存到本地 2 给自己写一封电子邮件 并将证书作为附件 3 在您的 iOS
  • 用于新闻源的 Firebase 扇出结构

    我有一个数据库posts users以及其他节点 例如经典的社交媒体应用程序 我正在继续对我的应用程序实施最佳实践 现在我想重写我的新闻报道 我关注的用户帖子 如 Instagram 中的主页选项卡 我读过一些关于fan out策略 现在我
  • 如何使用 CarrierWave 从 S3 获取真实文件

    我有一个读取文件内容并为其建立索引的应用程序 我将它们存储在磁盘本身中 但现在我使用 Amazon S3 因此以下方法不再有效 事情是这样的 def perform docId document Document find docId if
  • 声明与 TypeScript 一起使用的 JS 库

    有很多类似问题的线程 但据我所知 这个线程是独一无二的 我在用着jQuery 地址插件在我的应用程序中 并想在 TypeScript 文件中使用它 不幸的是 这儿没有绝对打字可用于库的脚本 当我尝试使用 jQuery address 时 我
  • 无法使用 Hibernate/PostgreSQL 将欧洲符号存储到 LOB 字符串属性中

    我在使用 Hibernate 3 6 10 的 PostgreSQL 8 4 中将特殊字符 如欧元符号 写入和读回 LOB 字符串属性时遇到问题 我所知道的是 PostgreSQL 提供了两种不同的方法来在表的列中存储大字符对象 它们可以直
  • 获取最新的ajax请求并中止其他请求

    我一直在寻找 这个问题看起来很简单 但找不到答案 我有多个请求调用不同的网址 但对于每个 url 我只想要一次结果 并且它必须是被调用的同一 url 中的最后一个结果 我现在的问题是 如何只得到最后一个 我看了一下这个 好像是3年前的了 h
  • Vista 从设置中安排任务

    我正在使用 Visual Studio 2008 中的安装向导项目部署 C 应用程序 让 Windows 安排我的应用程序定期运行 例如每 8 小时 的最简单方法是什么 我更喜欢在应用程序安装期间进行此调度 以简化最终用户的设置 Thank
  • TFS2015 中的构建 $(System.DefaultWorkingDirectory) 在哪里设置?

    我正在尝试修改此变量的值 因为它当前指向在代理上运行的任何构建的源文件夹 而不是构建的根目录 有谁知道我可以在哪里修改这个变量 我查看了代理的配置 json 文件 但没有找到任何相关内容 您可以定义 System DefaultWorkin
  • 使用 astropy.io 读取大量 FITS 时出现 OSError 24(打开文件过多)

    我正在尝试使用以下命令将一些 2000 FITS 加载到内存中astropy io fits def readfits filename with fits open filename as ft the fits contain a si
  • 不好 PhantomJS 意外退出

    testem ci not ok 1 PhantomJS Browser phantomjs home ubuntu nvm v0 10 12 lib node modules testem assets phantom js http l
  • Oracle 错误“数据类型不一致:预期 CHAR 为 LONG”

    我正在尝试运行以下查询来查找包含给定关键字的视图 select from ALL VIEWS where OWNER SALESDBA and TEXT like rownum 我收到以下错误消息 ORA 00932 inconsisten
  • 带有取消令牌的 NetworkStream.ReadAsync 永远不会取消

    证据在这里 知道这段代码有什么问题吗 TestMethod public void TestTest var tcp new TcpClient ReceiveTimeout 5000 SendTimeout 20000 tcp Conne