代码之家  ›  专栏  ›  技术社区  ›  mafu

我应该如何在WCF中同步列表?

  •  2
  • mafu  · 技术社区  · 15 年前

    我有一个WCF服务,它提供许多不同类型的项目列表。可以在服务器上更改列表。必须将每个更改发布到所有客户机,以确保每个客户机都有每个服务器列表的最新副本。

    目前我正在使用这个策略:登录时,每个客户机都会收到每个列表的当前状态。每次更改时,添加或删除的项都使用各自的回调方法发送给所有客户机。

    缺点是我必须为每个列表创建一个新的回调方法,因为这些项的类型不同,不能使用单个回调方法发送。有没有我可以应用的模式?或者我真的需要为每个列表重复代码吗?

    编辑: 列表可能会经常更改,所以我希望避免在每次更改时发送整个列表。相反,我只是发送更改的项目。

    (编辑2:次要澄清)

    2 回复  |  直到 15 年前
        1
  •  2
  •   Allon Guralnek    15 年前

    根据您的答案,提供一个接受字符串的方法,该字符串指定客户端要订阅的列表的名称。使用 Dictionary<string, List<IWcfCallbackContract>> .

    这个 ListChanged 回调方法应包含三个参数: string listName , ChangeType changeType (何处) ChangeType 是一个枚举,指定该项是被添加、删除还是更新)以及最后一个 object changedItem . 您还必须使用 ServiceKnownTypeAttribute 指定可以在 changedItem 争论。

    当列表中的项目发生更改时,请从 Dictionary<> 对象,并使用ListChanged方法通知每个对象。客户应将 变更项目 System.Object 以其期望的任何类型(根据 listName 争论)。

        2
  •  0
  •   mafu    15 年前

    我能想到一个解决办法,但感觉有点奇怪,我也不太自信。

    服务器为每个列表提供了一个通用的订阅方法。列表的名称作为参数传递。在更改任何列表时,服务器将发送更改列表的名称以及更改的项目。问题是,通常无法传递该项,因为回调约定只有一个“listwaschanged”方法(我绝对希望避免为每个列表使用新的回调方法,请参见问题)。

    但是,可以通过将序列化为字符串的更改项传递来解决此问题。通过使用NetDataContractSerializer,客户机可以轻松地重建序列化项,并将其传递给每个列表的正确处理程序。

    你觉得这个怎么样?这是可行的吗?一开始我认为这会严重影响性能,但第二次考虑时,我们无论如何都必须序列化每个项。唯一增加的性能影响是字符串的序列化,这不应该太多。

    由于这听起来有点令人困惑,下面是一个伪代码实现:

    服务器:

    // let's call it SyncList - a list that sends updates on changes
    class SyncList<T> : List<T>
    {
        // this is called on every change of the list
        void OnListChanged<T (string name, T item)
        {
            // serialize the item
            string ser = NetDataContractSerializer.Serialize(item);
            // send the item together with the name of the list
            WcfCallbackChannel.ListChanged (name, ser);
        }
    }
    

    客户:

    // this stores each of the lists
    Dictionary<string, List<T>> _Lists;
    
    // the list callback implementation
    class WcfCallbackImplementation : IWcfCallbackContract
    {
        // called on every change of ANY list
        void ListChanged (string name, string item)
        {
            // get the item back
            var item = NetDataContractSerializer.Deserialize (item);
            // add/remove/update item
            _Lists[name].Add (item);
        }
    }
    
    推荐文章