【问题标题】:Data persistance in Web Services?Web 服务中的数据持久性?
【发布时间】:2012-06-27 16:31:04
【问题描述】:

.NET Web 服务中的数据持久性解决方案有哪些?

我有一个网络服务。我给我的网络服务一个 id 并且这个返回正确的对象。

        [OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "/GetMyObject?id={id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        MyObject GetMyObject(string id);

我不想使用数据库。我想将我的对象集合保存在“内存”中。所以我决定像这样在我的网络服务中创建一个简单的对象

    public class Service : IService
    {
        List<MyObject> list = new List<MyObjec>();

        public Service()
        {
            list.Add(new MyObject() { Id = 1, Data = ...} );
            list.Add(new MyObject() { Id = 2, Data = ...} );
            list.Add(new MyObject() { Id = 3, Data = ...} );
            list.Add(new MyObject() { Id = 4, Data = ...} )
            ...
        }

        public MyObject GetMyObject(string id)
        {
            // code to get my object from the list
            return myObject;
        }
}

它可以工作,但是每次我调用我的 web 服务时都会调用构造函数,我想初始化这个列表一次并稍后对其进行修改。我应该如何初始化我的列表并将其持久化?

【问题讨论】:

  • 目前我不介意并发性,但是在最终解决方案中,我将不得不使用列表以外的其他东西。
  • 我不确定 Web 服务中数据持久性的定义。如果您必须重新启动服务和服务器,清除所有内存,您是否需要持久化数据?

标签: c# .net web-services


【解决方案1】:

您可以使用静态集合:

private static List<MyObject> list = new List<MyObjec>();

当然,由于这是一个多线程应用程序,您可能可以同时访问此集合,因此您必须确保同步访问它。或者,如果您使用的是 .NET 4.0,只需使用线程安全的 ConcurrentBag&lt;T&gt;

private static ConcurrentBag<MyObject> list = new ConcurrentBag<MyObjec>();

当然,您应该非常清楚,通过使用内存结构来存储数据,您的数据生命周期基本上与 Web 应用程序的生命周期相关联。并且由于 IIS 可以随时回收应用程序域(一段时间的不活动,达到特定的 CPU/内存阈值)您存储到内存中的所有内容都将变为无效。

顺便说一句,如果你走那条路,每次重新编译你的 Web 服务时,都要做好经常发生这种情况的准备,因为通过重新编译,你基本上是在修改 bin 文件夹中的程序集,而 Web 服务器将简单地回收应用程序.

所以,是的,所有这些文字墙都告诉您将数据保存在内存中以外的其他地方 :-) 您有很多可能性,从不同格式的文件、数据库、嵌入式数据库......

【讨论】:

  • 当我启动我的 web 服务项目时,如何初始化我的列表一次?
  • 您可以将static constructor 用于 Web 服务类,CLR 保证每个 AppDomain 生命周期只调用一次。
【解决方案2】:

或者,您可以将服务设为单例

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                 ConcurrencyMode = ConcurrencyMode.Single)]
class Service
...

但是,这种方法在未来会导致巨大的问题。不要在内存中存储任何东西。如果这样做,则将状态嵌入到应用程序中。这导致实现高可靠性和可扩展性所需的大量工作。没有状态,没有痛苦。

【讨论】:

  • 如果你这样做,你不应该再使用List&lt;T&gt;,因为如果你有2个web方法的并发调用你会得到损坏的数据。
  • @oleksii 这个解决方案对于将一直被调用的网络服务是否有效?多台计算机每毫秒?
  • @DarinDimitrov 是的,你是对的,我为此添加了 ConcurrencyMode.Single。或者,Dran 可以在您的回答之后使用ConcurrantBag&lt;T&gt;
  • @DranDane 此解决方案用于快速测试。我不会在高性能应用程序中使用它。
【解决方案3】:

WCF 已内置 instance management

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    相关资源
    最近更新 更多