Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 过滤BlockBuffer.ReceiveAsync的正确方法_C#_.net_Task Parallel Library_Async Await_Tpl Dataflow - Fatal编程技术网

C# 过滤BlockBuffer.ReceiveAsync的正确方法

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

你好

我有一个用于rpc调用的TPL数据流网格

它有两个未链接的流,简化后如下所示:

输出流量:

  • 用于存储输出的块缓冲区
  • ActionBLock将输出发送到服务器并生成发送id
和输入流:

  • while循环接收数据
  • TransformBlock来解析数据
  • 用sentid保存应答的BlockBuffer
有一个问题:当我从不同的线程打电话时,我可能会弄乱答案,所以我需要过滤它

我的rpc调用:

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();
}