需要一个更好的"回调调度程序"组件设计

dar*_*key 5 c# algorithm

从客户端应用程序我发送请求/事务(包含执行(和参数)+ transactionID的操作)到远程队列.远程服务器在某个时候将请求出列,并且需要一些时间来处理它.

一旦完成处理它,它就会在客户端队列上发送一个响应(包含应用响应+ transactionID)...所以这是一个完全"断开连接"的通信模式,客户端可以将响应映射到请求是通过transactionID.

消息响应在客户端出列,并与原始请求匹配(基于transactionID).

我现在正在做的是,当客户端将请求发布到服务器队列时,它会向保留transactionId和callback(委托)的字典添加回调.这是一个Dictionary<int, object>将transactionId映射回回调用操作结果调用的回调.

回调/委托存储为对象,因为根据请求,回调委托签名是不同的(例如,响应可以返回a List<string>而另一个响应可以返回int).

当客户端队列使响应出列时,它知道响应的类型(因此知道回调的相应签名),因此它根据transactionID从字典中获取回调.然后它将对象强制转换回相应的委托类型并调用回调.

我发现这种方法不是很"性感",但我并没有真正看到另一种方法来执行这样的任务.

有没有更好的方法来执行此操作?

如果问题不够明确,请告诉我并通过一些编辑进行澄清.

Pei*_*ein 3

您可能会发现响应式扩展是此类消息传递的便捷工具。

首先,让所有响应实现某个接口或基类,例如 IMessage。每种类型的响应都应该封装在一个单独的类中,如下所示

public interface IMessage
{
    int TransactionId { get; }
}

public class UserListMessage : IMessage
{
    int TransactionId { get; set; }
    public List<string> Users { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后让你的消息队列实现IObservable<IMessage>。反应式扩展提供了一个名为 的现成可用的实现Subject<T>,您可能想要包装它或其他东西。

Observable 实现了一种Subscribe(IObserver<IMessage> observer)将观察者存储在内部列表中某处的方法。当新的响应到达时,OnNext(IMessage message)每个订阅的观察者都会调用一个方法。

最后,您的响应处理注册代码可能如下所示:

var subscription = myQueue
    .OfType<UserListMessage>()
    .Where(msg => msg.TransactionId == id)
    .Subscribe(callback);
Run Code Online (Sandbox Code Playgroud)

这将为具有给定事务 ID 的 UserListMessage 类型的消息注册回调。也许您还想在某个地方取消订阅。那将是:

subscription.Dispose();
Run Code Online (Sandbox Code Playgroud)

这是 Rx 的一个简短示例。现在去寻找一些更详细的教程。