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# 使用反应式扩展将请求和响应配对_C#_.net_System.reactive - Fatal编程技术网

C# 使用反应式扩展将请求和响应配对

C# 使用反应式扩展将请求和响应配对,c#,.net,system.reactive,C#,.net,System.reactive,场景: 我将请求发送到服务器队列(我使用RabbintMQ异步处理消息)。当服务器处理请求时,它会对不同的队列生成两个响应 我想使用RX订阅响应,但也可以访问相应的请求 到目前为止我拥有的: 我使用EventAggregator,它使用反应式扩展并公开事件流的IObservable: public interface IEventAggregator { void Publish<TEvent>(TEvent sampleEvent); IObservable<

场景:

我将请求发送到服务器队列(我使用RabbintMQ异步处理消息)。当服务器处理请求时,它会对不同的队列生成两个响应

我想使用RX订阅响应,但也可以访问相应的请求

到目前为止我拥有的:

我使用EventAggregator,它使用反应式扩展并公开事件流的IObservable:

public interface IEventAggregator
{
    void Publish<TEvent>(TEvent sampleEvent);
    IObservable<TEvent> GetEvent<TEvent>();
}
这会更好:

private void OnResponse(
    RequestSent request, 
    ResponseFromQueue1 response1, 
    ResponseFromQueue2 response2)
{
   //actually, this would simplify implementation of my logic a lot
}

是否可以使用RX?

您可以使用
SelectMany
,假设您可以使用类似ID的内容将请求与响应关联起来

trigger.SelectMany(requestData => {
  //We need to share this
  var id = Guid.NewGuid();

  //Publish your event
  eventAggregator.Publish(new Request { ID = id, /*...*/ });

  //Start listening for the two responses
  //Grab only the first item matching the IDs
  var left = eventAggregator.GetEvent<ResponseFromQueue1>().First(res => res.ID == id);
  var right = eventAggregator.GetEvent<ResponseFromQueue2>().First(res => res.Id == id);

  //We are done once both values have emitted.
  return left.Zip(right);
}, (request, responses) => {
  /*Here you will have access to the request and an array of the responses*/
});

我不确定是什么触发了你的信息发布。可以是按钮单击,也可以是间隔计时器。好的,实际上是EventAggregator.GetEvent()。发送的请求必须在SelectMany…聪明的解决方案之外发布@在Paul的解决方案中,只需将
触发器
替换为
EventAggregator.GetEvent()
并更改
var id=requestData.id
并删除他在那里的
Publish()
调用。很好的调用@Brandon。我更新了一个示例,其中包括您的修复。
private void OnResponseFromQueue1(RequestSent request, ResponseFromQueue1 response)
{
   I need access to both request and respone
}
private void OnResponse(
    RequestSent request, 
    ResponseFromQueue1 response1, 
    ResponseFromQueue2 response2)
{
   //actually, this would simplify implementation of my logic a lot
}
trigger.SelectMany(requestData => {
  //We need to share this
  var id = Guid.NewGuid();

  //Publish your event
  eventAggregator.Publish(new Request { ID = id, /*...*/ });

  //Start listening for the two responses
  //Grab only the first item matching the IDs
  var left = eventAggregator.GetEvent<ResponseFromQueue1>().First(res => res.ID == id);
  var right = eventAggregator.GetEvent<ResponseFromQueue2>().First(res => res.Id == id);

  //We are done once both values have emitted.
  return left.Zip(right);
}, (request, responses) => {
  /*Here you will have access to the request and an array of the responses*/
});
//Set up the queue first    
eventAggregator.GetEvent<RequestSent>()
  .SelectMany(requestSent => {
     var id = requestSent.ID;
     var left = eventAggregator.GetEvent<ResponseFromQueue1>().First(res => res.ID == id);
  var right = eventAggregator.GetEvent<ResponseFromQueue2>().First(res => res.ID == id);

  return left.Zip(right);
}, (request, response) => {/**/});

//...Sometime later
eventAggregator.Publish(new Request{});