【问题标题】:How to write a WCF service with in-memory persistent storage?如何使用内存中持久存储编写 WCF 服务?
【发布时间】:2009-12-01 13:53:07
【问题描述】:

我编写了一个 WCF 服务,但存储在服务实现中的数据不会在调用之间持续存在,即使存储在静态变量中也是如此。我能做什么?

服务实现如下:

public class Storage : IStorage
{
    protected static object[] _data;

    #region IStorage Members

    public void Insert(object[] data)
    {
        lock (_data)
        {
             _data = _data.Concat(data).ToArray();
        }
    }

    public object[] SelectAll()
    {
        lock (_data)
        {
            return (object[])_data.Clone();
        }
    }

    #endregion
}

服务主机是一个控制台应用程序:

static void Main(string[] args)
{
    ServiceHost serviceHost =
       new ServiceHost(typeof(TimeSpanStorage));
    serviceHost.Open();
    Console.WriteLine("Service running.  Please 'Enter' to exit...");
    Console.ReadLine();
}

【问题讨论】:

    标签: c# .net wcf persistence


    【解决方案1】:

    默认情况下,WCF instanceMode 设置为每次调用,这意味着服务中使用的数据特定于用于该方法调用的该客户端。

    在您的实施中尝试添加

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single)]
    public class MyService: IService
    

    这使得服务本质上是一个单例。

    【讨论】:

    • 将上下文模式设置为Single 不一定是正确的做法——这将不允许每个事务的状态。使用DurableOperation 是更好的选择。
    • 我同意它不会允许持久服务所做的事务控制。当你想要扩展时,单例模式 defo 有它的限制。 “数据......在调用之间不会持续存在”只是让我觉得 OP 是在追求一些简单的事情。
    • 将 InstanceContextMode 设置为 Single 是一个可怕的想法 - 您的 WCF 服务类现在是一个单例,并且您已经序列化了所有请求的处理(杀死任何性能),或者您需要处理多线程问题(困难且容易出错)。最好的选择是持久服务,它实际上只是将它们的状态存储在持久存储(也称为数据库)中。
    • 再次,我同意这将是最终实现服务的方式,如果它需要持久/高性能。如果您只是希望在使用 WCF 时在调用之间保留一个数组,那么这可能有点繁重。 OP 未指定。
    • 它在我的测试中有效。我不在乎它是否会在服务停止时丢失数据,所以我对这种方法没有任何抱怨。
    【解决方案2】:

    您要做的是创建一个durable service

    WCF 持久服务是 WCF 服务 操作可以记住的地方 私有变量的值(= 服务状态)介于两者之间 重新启动服务主机和/或 客户。

    【讨论】:

    • 感谢您的回答。我没有在 Durable 服务中找到内存持久性选项。有没有?还是只是数据库持久性选项?
    【解决方案3】:

    您是否希望在您的 ServiceHost 实例的生命周期之后保留数据?如果是这样,那么我同意持久服务是有意义的。

    但是,如果您只想在对 WCF 服务的调用之间保持数据在服务处于活动状态时,那么在我看来,持久服务是多余的。使用静态数据是完全可以接受的;这正是我在 WCF 项目中所做的。事实上,您所展示的代码应该可以工作,所以这里发生了其他事情。

    Main() 方法真的如您所展示的那样吗?如果是这样,那就有问题了。一旦启用了 WCF 的控制台应用程序启动,它就会立即关闭,同时使用 WCF 服务。您需要有一些逻辑来保持控制台应用程序处于活动状态,因为 WCF 服务只会在控制台应用程序运行时保持“托管”状态。

    如果这不是问题,请告诉我,我将添加一个简单应用程序的完整代码来演示如何执行此操作。

    【讨论】:

    • 没有 Main 方法有一个 Console.ReadLine 调用。对问题进行了编辑以反映这一点。
    • “当服务存在时”是什么意思?它的意思是“当服务主机控制台应用程序正在运行时”?
    • @Jader Dias:是的,如果您只想在ServiceHost 控制台应用程序运行时保留数据,那么没有理由使用持久服务方法。持久服务方法将起作用,但静态数据方法也将起作用(同样,这就是我在 WCF 服务项目中使用的方法)。
    • 感谢您对我的怀疑的确认
    【解决方案4】:

    添加:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    

    在您的类之上,您将拥有一个单一实例的服务(即类属性保持不变)并允许多个并发连接。

    现在你必须照顾你的财产读/写,即像你已经做过的那样使用锁(或其他一些技术)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多