如何将 Task.WhenAny 与 ReadLineAsync 结合使用从任何 TcpClient 获取数据

2023-12-09

通过我的方式完成所有异步/等待(来自线程池),我遇到了一个有趣的挑战。

我有一个在 WPF 应用程序中运行的 TCP 服务器,它接受客户端并将它们存储在List<>像这样:

private List<Client> clients = new List<Client>();
while (running && clientCount <= maxClients)
{
    Client client = new Client(await server.AcceptTcpClientAsync());
    await client.WriteLineAsync("Connected to the Server!");
    clients.Add(client);
    clientCount++;
}

所以我想做的是遍历我的客户列表,如果收到任何数据,我想将其附加到文本框。我意识到这可能不是最好的方法为了实现这一目标,我愿意接受建议,但这就是我目前的结构。

一键启动循环,不断调用和等待AllReadLineAsync()

private async void btnStartReadLoopClick(object sender, RoutedEventArgs e)
{
    btnStartReadLoop.IsEnabled = false;
    while(server.clientCount > 0)
    {
        string text = await server.AllReadLineAsync();
        txtOutputLog.AppendText("[client] " + text + "\n");
    }
}

这是这个函数:

public async Task<string> AllReadLineAsync()
{
    var tasklist = new List<Task<string>>();

    foreach (var client in clients)
        tasklist.Add(client.ReadLineAsync());

    while (tasklist.Count > 0)
    {
        Task<string> finishedTask = await Task.WhenAny(tasklist);
        if (finishedTask.Status == TaskStatus.RanToCompletion)
            return await finishedTask;

        tasklist.Remove(finishedTask);
    }

    return "Error: No task finished";
}

该函数遍历客户端列表并创建一个List<Tast<string>>所有的ReadLineAsync() tasks.

在任何给定时间,我可能只有 1 或 2 个客户端实际发送数据,所以我不能WhenAll()我试过了WhenAny() and WaitAny()没有成功。

未来的谷歌用户请注意: WaitAny()就好像Wait()并且正在阻塞。不要在 UI 线程上执行此操作。而是使用WhenAny()并等待它。

因此,我当前的实现是可行的,但我无法弄清楚如果其他客户端不发送数据,消息将从 1 个客户端构建的错误。

TL;DR:我正在使用吗WhenAny()正确还是有更好的方法让我等待 ReadLineAsync 并将结果传递到文本框?

EDIT:这是我看到的行为 我按以下顺序输入:左、右、左 2、右 2、左 3、右 3 似乎有些消息被丢弃了?

enter image description here

EDIT 2:我在MSDN博客上找到了我复制的代码片段的来源:https://blogs.msdn.microsoft.com/pfxteam/2012/08/02/processing-tasks-as-they-complete/

此代码片段专门用于迭代任务列表,确保它们全部完成。我不关心任务是否重复,所以我需要修改代码以始终检查整个任务列表,而不是删除任何任务。


似乎有些消息被丢弃了?

是的。因为异步工作是started当您调用他们的方法时(例如,ReadLineAsync)。当其中之一完成时(Task.WhenAny),您的代码放弃其他任务。但它们仍在继续运行——它们仍在从套接字中读取数据,而它们读取的任何内容都将被丢弃。

AFAIK,当您开始从同一个套接字读取时,行为未定义again- 它可能会读取接下来的内容,或者可能会排队。我确实知道您不应该同时从套接字(或任何流)发出多个读取。

插座并不完美匹配async, 因为他们can随时发送数据。您应该使用 Rx 或事件来代替。有可能使async工作,但它非常复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Task.WhenAny 与 ReadLineAsync 结合使用从任何 TcpClient 获取数据 的相关文章

  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 在 Windows 服务中使用 OleDb 从 Excel 读取数据?

    免责声明 我知道这是一种不好的做事方式 这是我们与客户的唯一选择 Problem 我们需要每隔 x 时间从 Excel 文件读取数据 数据通过第三方 Excel 插件不断变化 应用程序的环境是 Windows XP SP1 和 Net 2
  • 在 C/C++ 中绘制填充椭圆的简单算法

    在SO上 找到了以下绘制实心圆的简单算法 for int y radius y lt radius y for int x radius x lt radius x if x x y y lt radius radius setpixel
  • 如何在 C++ 中从模板基类的构造函数调用模板超类的构造函数?

    我正在使用 sublimetext3 用 c 进行编程 我的程序有一个名为 Array 的超类和一个名为 IntArray 的子类 这两个类都是模板类 目前 我在编译该程序时遇到问题 它不断在我的 IntArray cpp 文件中给出错误
  • ASP.NET 中的 thread.sleep

    我正在为我的网站模拟彗星实时馈送协议 因此在我的控制器中我添加 while nothing new before timeout Thread Sleep 1000 但我注意到添加此功能后整个网站变慢了 调试后我得出结论 当我打电话时Thr
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • 如何在 C++ 中初始化嵌套类的构造函数

    我在初始化嵌套类构造函数时遇到问题 这是我的代码 include
  • 实体框架中的导航属性是什么

    我是实体框架的新手 当Visual Studio创建模型图时我们主要可以看到Entities Propertie和Navigation Properties这两个东西 那么这些Navigation Properties是什么 如何使用它们
  • 合并大文件的最佳方法是什么?

    我必须合并数千个大文件 每个大约 200MB 我想知道合并这些文件的最佳方法是什么 行将有条件地复制到合并文件中 可以使用 File AppendAllLines 或使用 Stream CopyTo 吗 使用 File AppendAllL
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 在 C# 中为 ListBox 分配数据源时,如何从 ListBox 中删除所选项目?

    在 C 中为 ListBox 分配数据源时 如何从 ListBox 中删除所选项目 尝试删除时出现错误 设置 DataSource 属性后 无法修改项目集合 但是当我尝试从数据源 数据表 中删除项目时 它会抛出错误 因为 数据行不在当前行集
  • 更快的 WinSock sendto()

    我使用的是 Windows Server 2008 我的程序是用 C 编写的 我在 while true 循环中使用 WinSock2 和 sendto 来发送数据包 代码如下 while true if c snd gt max c sn
  • 具有可导出私钥的证书的“错误密钥”例外

    我正在尝试使用非对称加密来加密然后解密文件 我已经使用 makecert 创建了一个测试证书并将其安装到我的个人本地计算机存储中 将来我必须在多个服务器上安装此证书 这就是为什么我使用 pe 标志创建它 即使用可导出的私钥 证书已成功创建并
  • 从不同的线程访问对象

    我有一个服务器类 它基本上等待来自客户端的连接 在该类中 我创建了一个 NetworkStream 对象 以便能够从客户端接收字节 由于 NetworkStream Read 方法不是异步的 这意味着它将等到从客户端读取字节才能继续执行类似
  • RC4 实现与 openssl 输出不匹配

    我的目标是在 C C 中实现 RC4 流密码 并确保它产生与使用时相同的输出openssl命令 按照伪代码维基百科 https en wikipedia org wiki RC4 该实现似乎有效 因为它可以加密和解密内容 但是 加密的输出与
  • Json.net 将数字属性序列化为字符串

    我正在使用 JsonConvert SerializeObject 序列化模型对象 服务器期望所有字段都是字符串 我的模型对象具有数字属性和字符串属性 我无法向模型对象添加属性 有没有办法将所有属性值序列化为字符串 我必须只支持序列化 而不
  • 如何使用 makecert 创建证书颁发机构证书?

    我正在尝试创建一个使用 SSL 和自签名证书的网站 这就是我所做的 创建权威证书 makecert n CN root signing authority r sv root pvk root cer 创建目标证书 makecert r p
  • IIS 中有 ASP.NET 网站管理工具吗?

    我正在使用 asp net 网站管理工具来管理项目中的不同角色 当前是客户和管理员 在vs 2008的开发过程中 管理角色非常容易 项目 gt Asp Net 配置 部署系统 IIS 时如何管理我的角色和用户 是否可以在 IIS 上运行 a
  • 为什么我们不在函数中通过引用传递 POD?

    我总是被告知我们不应该通过引用传递 POD 但最近我发现引用实际上根本不占用内存 那么为什么我们选择这样写 void DoSomething int iNumber 代替 void DoSomething const int riNumbe

随机推荐

  • Php从关联数组中获取键[重复]

    这个问题在这里已经有答案了 我怎样才能从数组中只获取整个第一行 我使用 Laravel 例如当我说 request all 我收到 array 2 email gt email protected password gt adms Wh 我
  • StringBuilder 在 C# 内部如何工作?

    如何StringBuilder work 它有什么作用内部 它使用不安全的代码吗 为什么它这么快 与 操作员 当您使用 运算符构建字符串时 string s 01 s 02 s 03 s 04 然后 在第一次串联时 我们创建一个长度为 4
  • 打印出整个目录树

    我现在拥有的代码 import os Tree Tree os listdir Dir gt gt gt print Tree New Folder Textfile1 txt Textfile2 txt 这不会打印出子目录中的文件 新建文
  • 在运行时使用类型变量创建类型列表[重复]

    这个问题在这里已经有答案了 我试图简化在函数中创建多个变量的方法 这些变量针对不同类型和不同操作重复 最终我将迁移到可以处理多种类型的单个函数 但我是分阶段进行的 我希望能够创建其类型的对象列表而不是列表 而不必在各处复制 粘贴对象类型 我
  • Tcl 中是否有与 C stdlib.h 中的“string to X”函数等效的函数?

    有标准功能 例如atof and atoi in C s stdlib h用于将字符串转换为浮点数 整数 也可以执行相反的操作 Tcl 中是否有类似的功能 或者我是否需要编写自己的流程来执行这些任务 一切都是字符串在 Tcl 中 但是需要数
  • 如何将JFreeChart库添加到JDK?错误:包 org.jfree.chart 不存在

    在获得了一些其他语言的经验后 我开始使用 Java 对于所有这些 我一直在使用 Atom 代码编辑器 所以我已经使用 Java 进行管理 但最近我发现我需要使用外部库 JFreeChart 我使用 JDK 8 在 cmd Windows 上
  • 在 pandas 对象列上调用 `str.len` 时遇到问题

    我有一个 Pandas DataFrame 其中有一个名为的字符串列title我想将每一行的条目转换为该字符串的长度 所以 abcd 将被转换为4 等等 我正在这样做 result df title result df title str
  • SQL WHERE ID IN (id1, id2, ..., idn)

    我需要编写一个查询来检索大量 id 列表 我们确实支持许多后端 MySQL Firebird SQLServer Oracle PostgreSQL 因此我需要编写标准 SQL id 集的大小可能很大 查询将以编程方式生成 那么 最好的方法
  • Python re.sub 问题

    大家好 我不确定这是否可能 但我想在正则表达式替换中使用匹配的组来调用变量 a foo b bar text find a replacement for me a and b desired output find a replaceme
  • 在 SQL 中按分区分组或迭代

    有关 SQL 分区的两部分问题 在 T SQL 中 当您使用 PARTITION BY 时 除了 row number 之类的方法之外 是否还有一种方法可以为每个分区分配唯一的编号 例如 row number 会产生 Action Time
  • android 中的可绘制文本与左对齐

    I am new to custom view and didn t know much about canvas in android I wanted to align a left drawable to right side of
  • 如何在c中的2个进程之间传递整数值

    如何在两个进程之间传递整数值 例如 我有 2 个进程 child1 和 child2 Child1 向 child2 发送一个整数 然后 Child2 会将该值乘以 2 并将其发送回 child1 然后子级 1 将显示该值 在 Window
  • 将 GCM 迁移到 FCM,我应该/可以保留当前的 ​​GCM 服务器端代码吗?

    我一直在使用 GCM 服务向 PHP 服务器中的现有应用程序发送通知 按照https stackoverflow com a 11253231 3286489 现在我正在考虑迁移到 FCM 正如所指出的https stackoverflow
  • 如何在javascript中用另一个div替换div?

    如何在javascript中用另一个div替换div 这就是我所拥有的 div main div
  • 字典样式替换多个项目

    我有一个很大的字符数据 data frame 我想根据其他语言中通常所说的字典进行转换 目前我正在这样处理 foo lt data frame snp1 c AA AG AA AA snp2 c AA AT AG AA snp3 c NA
  • C 语言中哪些地方需要使用 volatile 关键字

    我知道 volatile 关键字会阻止编译器优化变量并在读取变量时从内存中读取它 除了内存映射寄存器之外 还有哪些情况需要使用易失性呢 给定一个合格的编译器 我是否必须在这两种情况下将 test var 声明为易失性 1 在文件1 c中 i
  • 简化服务器和客户端上的 WCF 配置

    我们正在将旧版 Net Remoting 服务迁移到 WCF 在阅读了该主题一段时间后 我偶然发现了这个元数据谈话并在客户端上动态构建代理 它看起来很有前途 如果可能的话 我想要实现的是以最少的配置 即没有显式的配置 在一个 Web 应用程
  • 如何使用 Elastic beanstalk 加密负载均衡器和 Web 服务器之间的流量

    我想要在 Elastic Beanstalk 环境中加密负载均衡器和 Web 服务器之间的流量 亚马逊在这里有一个指南 https docs aws amazon com elasticbeanstalk latest dg configu
  • lm() 公式中的 rlang 双花括号

    是否可以使用 rlang tidy 求值运算符 在 lm 公式中 我知道您可以使用双花括号来定义一个通用函数 如下所示 my scatter lt function df xvar yvar ggplot df geom point aes
  • 如何将 Task.WhenAny 与 ReadLineAsync 结合使用从任何 TcpClient 获取数据

    通过我的方式完成所有异步 等待 来自线程池 我遇到了一个有趣的挑战 我有一个在 WPF 应用程序中运行的 TCP 服务器 它接受客户端并将它们存储在List lt gt 像这样 private List