.net 等待UDPClient.ReceiveAsync超时

b91juud3  于 2022-12-14  发布在  .NET
关注(0)|答案(4)|浏览(201)

我使用的UDPClient如下所示

dim c = New UDPClient(port)
client.CLient.ReceiveTimeout = 1
await client.ReceiveAsync()

然而,即使我设置了超时,等待也不会终止或抛出。这是正常的行为吗?

30byixjq

30byixjq1#

MSDN Library文章中明确提到了Socket.ReceiveTimeout:
获取或设置一个值,该值指定synchronousReceive调用将在多长时间后超时。
强调。当您使用ReceiveAsync()时,您执行的是与同步接收相反的操作。解决方法是使用System.Timers.Timer,它在调用之前启动,调用之后停止。关闭Elapsed事件处理程序中的套接字,以便ReceiveAsync()方法终止并出现ObjectDisposed异常。

m1m5dgzv

m1m5dgzv2#

是的。Socket上的异步方法没有实现超时。如果你需要异步操作的超时,你必须自己创建(例如,使用Task.DelayTask.WhenAny)。

bfhwhh0e

bfhwhh0e3#

我最近遇到了这个问题,这是我如何解决它:

async Task Listen(IPEndPoint ep, int timeout)
{
    using (var udp = new UdpClient(ep))
    {
        var result = await Task.Run(() =>
        {
            var task = udp.ReceiveAsync();
            task.Wait(timeout);
            if (task.IsCompleted)
            { return task.Result; }
            throw new TimeoutException();
        });

        Receive(result); // use the result
    }
}
qcuzuvrc

qcuzuvrc4#

不管怎么说,我是这样做的(也可能结合取消令牌):

public static async Task<byte[]> SendReceiveUdpAsync(IPEndPoint endPoint, byte[] packet, int timeout, CancellationToken cancellationToken)
{
    using var client = new UdpClient(endPoint.AddressFamily);
    await client.SendAsync(packet, endPoint, cancellationToken).ConfigureAwait(false);
    var task = client.ReceiveAsync(cancellationToken);
    var index = Task.WaitAny(new [] { task.AsTask() }, timeout, cancellationToken);
    if (index < 0)
        return null;

    return task.Result.Buffer;
}

技巧是在Task.WaitAny调用中等待UDP接收任务。

相关问题