c# - Task.WhenAny 的问题
问题描述
我正在使用 .NET 框架来创建一个服务器,它侦听 localhost 上的两个端口。这是一个简单的控制台应用程序。
当我继续连接到其中一个端口时它可以工作,但是在我第一个连接后,另一个没有响应。首先还活着。
这是我的代码:
static void Main(string[] args)
{
IPAddress hostIP = Dns.GetHostAddresses("127.0.0.1")[0];
List<TcpListener> listeners = new List<TcpListener>()
{
new TcpListener(hostIP, 6060),
new TcpListener(hostIP, 6061)
};
foreach (TcpListener listener in listeners)
{
listener.Start();
}
try
{
while (true)
{
Socket socket = AcceptAnyConnection(listeners).Result;
NetworkStream stream = new NetworkStream(socket);
byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
stream.Write(bytes, 0, bytes.Length);
//stream.Close();
socket.Close();
}
}
finally
{
foreach (TcpListener listener in listeners)
{
listener.Stop();
}
}
}
private static async Task<Socket> AcceptAnyConnection(List<TcpListener> listeners)
{
List<Task<Socket>> tasks = new List<Task<Socket>>();
foreach (TcpListener listener in listeners)
{
tasks.Add(AcceptConnection(listener));
}
Task<Socket> completedTask = await Task.WhenAny(tasks);
return await completedTask;
}
private static async Task<Socket> AcceptConnection(TcpListener listener)
{
Socket socket = await listener.AcceptSocketAsync();
return socket;
}
如果我连接到另一个端口,则等待 Task.WhenAny() 阻塞。
我一定做错了什么,但我不确定是什么。
顺便说一句,我确实对 .NET Core 控制台应用程序进行了同样的尝试,并且效果很好。
谢谢
解决方案
我建议将您的代码重构为类似的内容,然后从那里获取。也就是说,为每个侦听器运行一个无限循环。这避免了确保您一次只AcceptTcpClientAsync
为每个客户调用一次的问题。
(请注意,没有代码可以真正阻止听众。也完全未经测试 - 请仅将其用作指示采取的方法)
static void Main(string[] args)
{
IPAddress hostIP = Dns.GetHostAddresses("127.0.0.1")[0];
List<TcpListener> listeners = new List<TcpListener>()
{
new TcpListener(hostIP, 6060),
new TcpListener(hostIP, 6061)
};
var listenerTasks = listeners.Select(x => RunTcpListener(x)).ToArray();
Task.WaitAll(listenerTasks);
}
private static async Task RunTcpListener(TcpListener listener)
{
listener.Start();
try
{
while (true)
{
using (var client = await listener.AcceptTcpClientAsync())
{
var stream = client.GetStream();
byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
stream.Write(bytes, 0, bytes.Length);
client.Close();
}
}
}
finally
{
listener.Stop();
}
}
推荐阅读
- git - 我可以为 git add --patch 添加自己的选项吗?
- python - 带有 django 的动态 html 表
- iis - 具有报告查看器问题的 SSRS 未刷新
- python - 如何在 python 中使用三个 1D 数组绘制 3D 曲面图,因为我收到错误 Z 必须是二维的。如何将其转换为二维数组?
- python - python pandas loc返回空数据框
- android - PagerAdapter 中的 Android imageView 有奇怪的坐标
- azure - 传递到 Azure 通知中心的通知消息未到达设备 (Android)
- react-native - 如何使反应原生的android应用程序崩溃
- php - 如何使用 FPDF 使 pdf 页面的白色背景透明 - PHP
- python - 如何在循环Raspberry Pi时进行多次?Python