如何转换任务<tuple <e,r>&gt;进入任务<e>

时间:2015-07-02 02:37:27

标签: c# asynchronous

我第一次尝试编写简单的命令响应式通信的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);

如何转换/代理任务&lt; Tuple&lt; E,R&gt;&gt;通过私有方法返回到任务&lt; E&gt;为了SendCommandAsync()的好处?

THX

理查德。

3 个答案:

答案 0 :(得分:3)

只需将其设为异步。

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

答案 1 :(得分:1)

由于Tuple有两个值,您只需从公共私有中返回第一个值,即E。此值可用作Task.FromResult的结果,该值将根据值创建已完成的任务。

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

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

答案 2 :(得分:0)

您可以使用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();
}