如何将任务<元组>转换为任务

本文关键字:任务 转换 元组 | 更新日期: 2023-09-27 18:00:54

我第一次破解编写简单命令响应样式通信协议栈的TAP异步实现。

参考同步实现提供了几个公共方法

public E SendCommand(C command);
public E SendCommandAndRetrieveResponse(C command, out R response);

(其中 E 是某种形式的错误代码类型(,两者都调用一个共同的内部

E _SendCommandAndRetrieveResponse(C command, out R response);

在 SendCommand(( 的情况下传递一个虚拟响应。

所以我认为等效异步方法的签名将是

public Task<E> SendCommandAsync(C command);
public Task<Tuple<E, R>> SendCommandAndRetrieveResponseAsync(C command);

到目前为止一切顺利,但让我难倒的是,如果我遵循同步模型并使用通用私有

Task<Tuple<E, R>> _SendCommandAndRetrieveResponseAsync(C command);

如何将私有方法返回的任务<元组><E,R>>转换为任务以造福SendCommandAsync((?

感谢

理查。

如何将任务<元组<E,R>>转换为任务<E>

只需使其异步即可。

public async Task<E> SendCommandAsync(C command)
{
    var result = await _SendCommandAndRetrieveResponseAsync(command);
    return result.Item1;
}

由于 Tuple 有两个值,因此您可以简单地从公共私有中返回第一个值,即 E 。此值可用作 Task.FromResult 的结果,这将基于该值创建已完成的任务。

public Task<E> SendCommandAsync(C command)
{
    return Task.FromResult(_SendCommandAndRetrieveResponseAsync(command).Result.Item1);
}

注意:此解决方案使用 .NET 4.5 功能,请参阅此问题以了解替代解决方案,而不是 FromResult

您可以使用

ContinueWith调用将包含元组的任务转换为仅保存E的任务。这有一个副作用,即创建一个嵌套任务Task<Task<E>>,这可以通过解开它们来解决。

private Task<Tuple<E, R>> _SendCommandAndRetrieveResponseAsync(C command)
{
    Task<Tuple<E, R>> result = //.....
    return result;
}
public Task<E> SendCommandAsync(C command)
{
    return _SendCommandAndRetrieveResponseAsync(command)
        .ContinueWith(task => new TaskCompletionSource<E>(task.Result.Item1).Task)
        .Unwrap();
}