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