Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务的PerCall InstanceContextMode行为_C#_.net_Wcf_Basichttpbinding_Instancecontextmode - Fatal编程技术网

C# WCF服务的PerCall InstanceContextMode行为

C# WCF服务的PerCall InstanceContextMode行为,c#,.net,wcf,basichttpbinding,instancecontextmode,C#,.net,Wcf,Basichttpbinding,Instancecontextmode,我有一个WCF服务,它公开了一个带有basicHttpBinding的ServiceContract,因此据我所知,InstanceContextMode将设置为PerCall(因为basicHttpBinding不支持会话),而ConcurrenyMode将设置为Single 这个WCF的客户端是一个windows服务,它同时调用服务上的4个不同操作,在服务中我们使用了一个单例类,并且没有几个静态变量。我们一直面临一个问题,即错误的值被传递到某些DB存储过程 有了PerCall Instanc

我有一个WCF服务,它公开了一个带有basicHttpBinding的ServiceContract,因此据我所知,InstanceContextMode将设置为PerCall(因为basicHttpBinding不支持会话),而ConcurrenyMode将设置为Single

这个WCF的客户端是一个windows服务,它同时调用服务上的4个不同操作,在服务中我们使用了一个单例类,并且没有几个静态变量。我们一直面临一个问题,即错误的值被传递到某些DB存储过程

有了PerCall InstanceContextMode和Single concurrency mode,我知道每次调用都会创建一个新的服务instacne,因此我认为即使在服务实现和静态变量中有一些单例类(我们没有使其线程安全),所有对象都将被销毁,但我们观察到,在旧值上运行的SQL探查器正在通过DB

我们已经在一种三层架构中编写了我们的WCF服务代码,我指的是ServiceClass、BusinessLogicLayer和DataAccessLayer,PerCall设置为instanceContextMode当我们说服务实例在客户端请求完成后被销毁时,这是否意味着我们销毁了ServiceClass中的所有对象,BusinessLogicLayer和DataAccessLayer


请帮助我了解可能出现的问题

InstanceContextModePerCall意味着每次呼叫都会实例化一个新的服务类。AppDomain中的静态变量将不会重置。只要您的应用程序池不被回收,它们将在服务调用之间停留


从代码中删除所有静态数据,包括单例数据。它们从来都不属于您的体系结构。

许多WCF请求共享同一AppDomain。每个AppDomain都有静态变量。WCF对这些变量不做任何处理(事实上,它甚至无法发现它们的存在。你有责任维护它们

WCF不会销毁任何对象,因为它既不理解对象的含义,也不知道对象的存在

您提到的设置仅与服务对象相关


关于有状态服务器应用程序,我通常的建议是:您在这里使用的是错误的做法。您需要确保线程安全。如果工作进程关闭(部署、自动重新启动、服务器重新启动、应用程序错误使进程崩溃、断电、硬件故障等),您的数据将丢失。

尽管静态变量受到任何方式的限制,但作为最佳实践,需要保护它以实现线程安全。在服务停止/应用程序池回收之前,静态变量不会被销毁

对分布式web场不建议更改的数据使用静态变量,因为在故障切换过程中这些变量并不安全

Visual Studio 2012及更高版本附带内存分析器。但是简单的事情可以使用对象构造函数中的计数器来完成(仅在测试时),它可以判断是否在每个请求上创建了一个新实例

   [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Single)]
public class TestServiceWithStaticVars : ITestServiceWithStaticVars
{
   static int instanceCount = 0;
    public TestServiceWithStaticVars()
    {
        Interlocked.Decrement(ref instanceCount);
    }
    public string GetInstanceCount()
    {
        return string.Format("You have created {0} instance", instanceCount);
    }
让您知道是否可以轻松使用更好的实例计数器

[编辑]我现在无法评论


重新分配静态变量将采用您所说的新值。静态变量被加载到HighFrequencyHeap以进行频繁访问。有关更多信息

您使用单例的原因是什么?在您的体系结构中,这似乎是一种极不适合的模式。如果没有单例并使用一些适当的调试,您应该会很好。谢谢@usr,这帮助我更好地理解,是否有任何工具我指的是某种内存分析工具,用于了解/可视化内存中的对象以及服务期间和之后没有的对象我相信Jetbrains内存分析工具有一个快照差异工具。但它不会向您显示处于活动状态但已失效(已处置、配置错误等)的对象。我认为手工检查是一种方法。审核所有静态变量。感谢@nvoigt,它帮助我更好地理解,是否有任何工具我指的是某种内存分析工具来理解/可视化内存中的对象以及服务期间和之后没有的对象call@CSharped你可以试试上面提到的一些剖析器。谢谢,在我的例子中,我有一个导致所有问题的静态变量,我现在知道它将存储在相应服务的AppDomain中,若我的代码正在重新初始化该静态变量,该变量会接受新值吗?你能帮我理解它是怎么工作的吗