await UDPClient.ReceiveAsync with timeout



我正在使用UDPClient,如下所示

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

但是,等待不会终止或抛出甚至虽然我已经设置了超时。这正常吗行为?

MSDN Library 文章中明确提到了 Socket.ReceiveTimeout:

获取或设置一个值,该值指定同步接收调用超时的时间量。

强调添加。 当你使用 ReceiveAsync() 时,你正在做与同步接收相反的事情。 解决方法是使用在呼叫之前启动并在呼叫之后停止的 System.Timers.Timer 。 关闭 Elapsed 事件处理程序中的套接字,以便 ReceiveAsync() 方法以 ObjectDispose 异常终止。

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

我最近遇到了这个问题,这就是我解决它的方式:

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
    }
}

对于它的价值,这就是我的做法(也可能使用取消令牌的组合):

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 接收任务。

相关内容

  • 没有找到相关文章

最新更新