c# - 如何在不阻塞主线程的情况下实现UDP
问题描述
我使用的数据通过 UDP 到达。我想在不阻塞主线程的情况下创建几个 UDP 连接。我已经同步和异步地实现了 UDP 连接,但是它们都保持主线程锁定。我的代码永远不会到达'Console.WriteLine("Past the Async")'
目标是让 UDP 连接在后台运行。
谁能提供一些关于下一步要尝试什么,或者如何正确实现允许主线程仍然接收命令的异步版本的 UDP 的方向?
我注释掉异步版本的 ReceiveUdpData() 。
class Program
{
// The whole point of this is to not block the main thread.
static async Task Main(string[] args)
{
ReceiveUdpData();
Console.WriteLine("Past Receive UDP Data");
await foreach (var item in MessagesAsync())
{
Console.WriteLine(item);
}
Console.WriteLine("Past The Async");
}
// Synchronous connection to UDP.
public static void ReceiveUdpData()
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
var count = 0;
using (UdpClient client = new UdpClient(12345))
{
while (true)
{
Byte[] receiveBytes = client.Receive(ref remoteEndPoint);
count++;
Console.WriteLine(count);
}
}
}
// Async UDP connection
private static async IAsyncEnumerable<object> MessagesAsync()
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
var count = 0;
using (UdpClient client = new UdpClient(12345))
{
while (true)
{
UdpReceiveResult test = await client.ReceiveAsync();
count++;
yield return test.ToString();
}
}
}
}
解决方案
await
将通过安排在给定任务继续后运行的其余方法来“阻止”当前方法。它有点相似(在语义上与 不同Task.ContinueWith
),因此csharp Console.WriteLine("Past The Async")
只有在收到所有消息后才会执行。
您不能通过以“即发即弃”的方式在单独的任务上枚举 IAsyncEnumerable 来等待消息:
static async Task Main(string[] args)
{
PrintMessages();
Console.WriteLine("Past The Async");
}
public static async Task PrintMessages()
{
await foreach (var item in MessagesAsync())
{
Console.WriteLine(item);
}
}
但是如果你这样做,你的程序将在Main
退出后立即终止,所以你可能真的想等待,或者你可能还有其他一些可以执行的工作。
推荐阅读
- matlab - 仅针对满足 MATLAB 中特定方程的坐标绘制曲面
- python - 一次性为 numpy 单元格赋值
- google-apps-script - 谷歌电子表格:保持格式化数据不受 INDIRECT 影响
- python - Python 3 & Kivy:只对双击“不是”单击做出反应
- python - 无法使用 Python 代码访问 NSF 文件 - “注释错误:无法打开 ID 文件”
- android - 无法将元素添加到我从 firebase 获得的 Arraylist
- ios - 我无法在 iOS 14 中为具有 UIDatePickerStyle.inline 的 UIDatePicker 更改文本颜色
- azure-devops - 在 Azure 管道之间传递变量
- python-3.x - 连接来自两个不同来源的两个数据帧。如果数据框丢失,则无法处理情况
- tensorflow - 以最大验证准确度停止训练。这是一个好习惯吗?