简体   繁体   English

NET中的线程安全发布订阅

[英]Thread Safe Publish Subscribe in .Net

I created a simple set of interfaces and a class that allows me to publish the additions and removals of items in a generic dictionary. 我创建了一组简单的接口和一个类,使我可以在通用字典中发布项目的添加和删除。 Subscribers receive the entire list when they subscribe and after that, they get only the changes. 订阅者在订阅时会收到整个列表,此后,他们只会获得更改。

Although my solutions work, I am looking for something a little more standard, a little less home-grown. 尽管我的解决方案有效,但我正在寻找一些更标准,更便宜的产品。 Do you have any suggestions? 你有什么建议吗?

Notes on what I've found so far: 关于我到目前为止发现的注释:

I have been looking at Microsoft's Reactive Extensions (Rx). 我一直在研究Microsoft的反应性扩展(Rx)。 According to Jon Skeet's article "LINQ to Rx: second impressions" [1], he says "as soon as an observer subscribes, the observable publishes everything in the sequence to it (on a different thread, by default). Separate calls to Subscribe make the observable iterate over the sequence multiple times." 根据乔恩·斯凯特(Jon Skeet)的文章“ LINQ to Rx:第二印象” [1],他说:“观察者一订阅,可观察对象就会立即按顺序发布所有内容(默认情况下,它在另一个线程上)。分别调用订阅使可观察的对象遍历整个序列多次。” This sounds like the basic idea, but I can't find any specific examples and I'm not really sure about the thread-safety of "Subject" or "AsyncSubject" yet. 这听起来像是基本思路,但是我找不到任何具体示例,而且我不确定“ Subject”或“ AsyncSubject”的线程安全性。

Notes on my home-grown solution: 关于我自己的解决方案的注意事项:

The structure that is delivered to subscribers looks like this: 传递给订户的结构如下所示:

/// <summary>
/// Interface for a set of changes that are being published.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TItem"></typeparam>
public interface IPublication<TKey, TItem>
{
    /// <summary>
    /// Version of the list.
    /// </summary>
    long Version { get; }
    /// <summary>
    /// Items that were added or updated.
    /// </summary>
    IEnumerable<TItem> ChangedItems { get; }
    /// <summary>
    /// Keys to items that were removed.
    /// </summary>
    IEnumerable<TKey> RemovedKeys { get; }
}

The subscribers themselves must implement this interface: 订户本身必须实现此接口:

/// <summary>
/// Interface for a subscriber that will receive IPublication{TKey, TItem} deliveries from a publisher.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TItem"></typeparam>
public interface ISubscribe<TKey, TItem>
{
    void Deliver(IPublication<TKey, TItem> pub);
}

And of course my generic dictionary publisher class has this method: 当然,我的通用词典发布者类具有以下方法:

/// <summary>
/// Adds the give subscriber to the list of subscribers and immediately publishes the
/// dictionary contents to the new subscriber. The return value may be disposed when
/// the subscriber wishes to terminate it's subscription.
/// </summary>
/// <param name="subscriber"></param>
/// <returns></returns>
public IDisposable Subscribe(ISubscribe<TKey, TItem> subscriber);

[1] https://codeblog.jonskeet.uk/2010/01/19/linq-to-rx-second-impressions/ [1] https://codeblog.jonskeet.uk/2010/01/19/linq-to-rx-second-impressions/

This is not really an answer but tedious to put into the comments so putting it here... Not sure why are you looking at a standard out of box solution when your custom solution is easy to build and will work? 这不是一个真正的答案,但是要在评论中添加内容很繁琐,因此将其放在此处...不知道为什么您的自定义解决方案易于构建并且可以正常工作时,为什么要使用标准的现成解决方案? Events are the simplest (and standard) way of achieving publisher-subscriber model but they are not thread-safe and also suffer from tight coupling between subscriber and publisher. 事件是实现发布者-订阅者模型的最简单(和标准)方式,但是它们不是线程安全的,并且还遭受订阅者和发布者之间的紧密耦合。 MS patterns & practice group had published WCF based pattern but I think that you are looking for a fast in-process kind of code. MS模式和实践小组已经发布了基于WCF的模式,但是我认为您正在寻找一种快速的进程内代码。 Similarly, many other standard publish-subscribe solutions will be targeting application integration (ESB). 同样,许多其他标准的发布-订阅解决方案将以应用程序集成(ESB)为目标。 In case you didn't find any alternatives and decided to go with your custom solution then you mar refer this artcile that describes issues in implementing this design pattern. 如果您找不到其他选择并决定使用自定义解决方案,那么您可以参考该文章来描述实现此设计模式中的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM