首页 > 解决方案 > 如何在不阻塞主线程的情况下实现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();
            }
        }
    }
}

标签: c#multithreadingasynchronousudp

解决方案


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退出后立即终止,所以你可能真的想等待,或者你可能还有其他一些可以执行的工作。


推荐阅读