4

我创建了一个 WCF 服务,该服务从数据库中读取并发回结果。出于性能原因,我想在服务启动时缓存表(这发生在 Windows 服务 OnStart 中)。但是 WCF 中没有构造函数之类的东西(对吗?)所以我想出的最好的办法是创建一个 Init() 函数并像下面这样调用它:

protected override void OnStart(string[] args)
{
    mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));
    mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");
    ((DLSService.DLSService)mServiceHost.SingletonInstance).Init();
    mServiceHost.Open();
}

但是使用 SingletonInstance 并转换为正确的类型对我来说似乎并不那么优雅。是否有更优雅的方法可以在 WCF 中实现类似构造函数的功能?

4

4 回答 4

3

这可以通过像MbCache这样的记忆库来解决。我们正在做您正在寻找的东西;在应用程序启动时,我们调用我们想要缓存的每个服务操作,并且 MbCache 缓存连续调用的结果(即没有数据库往返来获取结果),直到缓存过期。

MbCache 确实具有相当大的复杂性,但一旦运行,它就可以很好地工作并为我们处理所有缓存逻辑。

于 2013-07-10T07:18:15.467 回答
3

推荐的最佳实践是使用 WCF 中的每次调用激活模型并保持服务完全无状态。

这意味着:每次客户端发出请求时,在服务器端,都会创建一个您的服务实现类的实例,进行请求的服务调用,然后再次销毁该服务类。

因此,将您的初始化代码放入服务实现类构造函数将是一个非常糟糕的主意——它将为每个请求执行。

您可以做的是有某种逻辑(在您的服务类中,或某些支持代码,例如某种管理界面)将您想要缓存的那些表加载到持久缓存中,例如 AppFabric 缓存之类的东西. 完成后,处理请求的多个服务实例可以使用该公共缓存来获得更好的性能。

于 2013-07-10T06:55:24.733 回答
1

您可以使用该IInstanceProvider接口来创建您的服务,请阅读本文了解更多信息。这是一个代码示例:

public class CustomInstanceProvider:IInstanceProvider
{

    public object GetInstance(InstanceContext instanceContext)
    {
        return GetInstance(instanceContext, null);
    }

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        return new DLSService.DLSService();
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {            
    }
}

var mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));   
mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");

foreach (var channelDispatcher in mServiceHost.ChannelDispatchers.OfType<ChannelDispatcher>())
{
    foreach (var endpointDispatcher in channelDispatcher.Endpoints)
    {
        endpointDispatcher.DispatchRuntime.InstanceProvider = new CustomInstanceProvider();
    }
}
mServiceHost.Open();
于 2013-07-10T06:58:54.597 回答
0

使用框架 4.5,您可以在服务实现代码中使用配置功能:

http://msdn.microsoft.com/en-us/library/hh205277(v=vs.110).aspx

于 2017-03-30T15:17:42.153 回答