【发布时间】:2019-12-06 09:09:21
【问题描述】:
我已阅读 Stephen Toub's blog 关于为 SocketAsyncEventArgs 制作自定义等待的内容。这一切正常。但我需要的是一个可取消的等待对象,并且该博客不涉及这个主题。不幸的是,Stephen Cleary 也没有在他的书中介绍如何取消不支持取消的异步方法。 我尝试自己实现它,但我因 TaskCompletionSource 和 Task.WhenAny 失败,因为使用可等待的我实际上并没有等待任务。 这就是我想要的:能够使用带有 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;
}
【问题讨论】:
-
你试过检查这个thread吗?
标签: c# sockets async-await cancellation socketasynceventargs