C# 过滤BlockBuffer.ReceiveAsync的正确方法
你好 我有一个用于rpc调用的TPL数据流网格 它有两个未链接的流,简化后如下所示: 输出流量:C# 过滤BlockBuffer.ReceiveAsync的正确方法,c#,.net,task-parallel-library,async-await,tpl-dataflow,C#,.net,Task Parallel Library,Async Await,Tpl Dataflow,你好 我有一个用于rpc调用的TPL数据流网格 它有两个未链接的流,简化后如下所示: 输出流量: 用于存储输出的块缓冲区 ActionBLock将输出发送到服务器并生成发送id 和输入流: while循环接收数据 TransformBlock来解析数据 用sentid保存应答的BlockBuffer 有一个问题:当我从不同的线程打电话时,我可能会弄乱答案,所以我需要过滤它 我的rpc调用: public async Task<RpcAnswer> PerformRpcCall
- 用于存储输出的块缓冲区
- ActionBLock将输出发送到服务器并生成发送id
- while循环接收数据
- TransformBlock来解析数据
- 用sentid保存应答的BlockBuffer
public async Task<RpcAnswer> PerformRpcCall(Call rpccall)
{
...
_outputRpcCalls.Post(rpccall);
long uniqueId = GetUniq(); // call unique id
...
var sent = new Tuple<long, long>(uniqueId, 0);
while (_sentRpcCalls.TryReceive(u => u.Item1 == uniqueId, out sent)) ; // get generated id from send function
return await _inputAnswers.ReceiveAsync(TimeSpan.FromSeconds(30));
}
public异步任务性能调用(调用rpccall)
{
...
_outpurtpccalls.Post(rpccall);
long uniqueId=GetUniq();//调用唯一id
...
var sent=新元组(uniqueId,0);
while(_sentRpcCalls.TryReceive(u=>u.Item1==uniqueId,out-sent));//从发送函数获取生成的id
返回wait_inputswers.ReceiveAsync(TimeSpan.FromSeconds(30));
}
正如你们所看到的,我有一个uniqueId,它可以帮助我确定这个电话的答案,但我如何过滤它并等待它呢
有一些缓冲区数组(可能是WriteOnceBlock?)是好方法吗?这些缓冲区将在rpc调用中创建并与筛选器链接?好的,我没有找到任何合适的方法,所以我做了一个肮脏的解决方法
while (true)
{
answer = await _inputAnswers.ReceiveAsync(TimeSpan.FromSeconds(5));
if (answer.Success)
{
if (answer.Answer.Combinator.ValueType.Equals(rpccall.Combinator.ValueType))
{
break;
}
else
{
// wrong answer - post it back
_inputAnswers.Post(answer.Answer);
}
}
else
{
// answer fail - return it
break;
}
}
一种方法是为每个id创建一个新块,并使用检查id的谓词将其链接到answers块,并将MaxMessages设置为1:
Task<Answer> ReceiveAnswerAsync(int uniqueId)
{
var block = new BufferBlock<Answer>();
_inputAnswers.LinkTo(
block,
new DataflowLinkOptions { MaxMessages = 1, PropagateCompletion = true },
answer => answer.Id == uniqueId);
return block.ReceiveAsync();
}
任务接收应答异步(int uniqueId)
{
var block=新的缓冲块();
_inputswers.LinkTo(
块
新的DataflowLinkOptions{MaxMessages=1,PropagateCompletion=true},
answer=>answer.Id==uniqueId);
return block.ReceiveAsync();
}