我已阅读Stephen Toub 的博客,关于为 SocketAsyncEventArgs 制作自定义等待。这一切正常。但我需要的是一个可取消的等待对象,并且该博客不涉及这个主题。不幸的是,Stephen Cleary 也没有在他的书中介绍如何取消不支持取消的异步方法。我试图自己实现它,但我在 TaskCompletionSource 和 Task.WhenAny 上失败了,因为使用 awaitable 我实际上并没有在等待任务。这就是我想要的:能够使用带有 TAP 格式的 Socket 的 ConnectAsync 并能够取消它,同时仍然具有 SocketAsyncEventArgs 的可重用性。
public async Task ConnectAsync(SocketAsyncEventArgs args, CancellationToken ct) {}
到目前为止,这就是我从 Stephen Toub 的博客中获得的内容(以及 SocketAwaitable 实现):
public static SocketAwaitable ConnectAsync(this Socket socket,
SocketAwaitable awaitable)
{
awaitable.Reset();
if (!socket.ConnectAsync(awaitable.m_eventArgs))
awaitable.m_wasCompleted = true;
return awaitable;
}
我只是不知道如何将其转换为 TAP 格式并使其可取消。任何帮助表示赞赏。
编辑1: 这是我如何正常取消的示例:
private static async Task<bool> ConnectAsync(SocketAsyncEventArgs args, CancellationToken cancellationToken)
{
var taskCompletionSource = new TaskCompletionSource<bool>();
cancellationToken.Register(() =>
{TaskCompletionSource.Task
taskCompletionSource.TrySetCanceled();
});
// This extension method of Socket not implemented yet
var task = _socket.ConnectAsync(args);
var completedTask = await Task.WhenAny(task, taskCompletionSource.Task);
return await completedTask;
}