我第一次尝试编写简单的命令响应式通信的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
理查德。
答案 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();
}