C# 双工Wcf服务应用程序,列表保留上次运行的应用程序的值

C# 双工Wcf服务应用程序,列表保留上次运行的应用程序的值,c#,wcf,C#,Wcf,我实现了一个使用“WCF服务应用程序”构建的服务。 该应用程序还有两个客户端,它们可以作为双工来工作。 (wsDualHttpBinding) [服务行为(InstanceContextMode=InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Multiple)] 公共类服务1:IService1 { 私有静态列表lst=新列表(); 公开无效订阅() { 第1条增补(1); //.... 奇怪的是,当我运行应用程序时,列表

我实现了一个使用“WCF服务应用程序”构建的服务。 该应用程序还有两个客户端,它们可以作为双工来工作。 (wsDualHttpBinding)

[服务行为(InstanceContextMode=InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Multiple)]
公共类服务1:IService1
{
私有静态列表lst=新列表();
公开无效订阅()
{
第1条增补(1);
//....
奇怪的是,当我运行应用程序时,列表会“记住”上次运行时的值。。 而lst.Count随着整个应用程序的不同运行而变得越来越大。 我找不到原因。 我还尝试将InstanceContextMode设置为other,然后设置为single,但没有帮助。 谢谢
Liron。

这是因为您使用的是静态字段,它在所有调用之间共享

因为
InstanceContextMode=InstanceContextMode.Single
。它使您的服务在单音模式下工作,这意味着只有一个
Service1
类的实例是为您的所有客户端和连接创建的

只有一个
InstanceContext
对象用于所有传入呼叫,并且不会在呼叫后循环使用。如果服务对象不存在,则会创建一个服务对象

您可能应该改为使用
InstanceContextMode.PerSession
,并将字段更改为instance:

public class Service1 : IService1
{
    private List<int> lst = new List<int>();
公共类服务1:IService1
{
私有列表lst=新列表();

让我们把WCF从图片中去掉。如果我有下面的代码,您希望输出是什么

public class Foo
{
    private static int number = 0;

    public int GetNumber()
    {
        number = number + 1;
        return number;
    }
}

public static Main()
{
    var foo1 = new Foo();
    Console.WriteLine(foo1.GetNumber());
    Console.WriteLine(foo1.GetNumber());

    var foo2 = new Foo();
    Console.WriteLine(foo1.GetNumber());
}
您应该看到
1、2、3

WCF不会修改
static
的工作方式。如果您有两个类实例,它仍然共享静态变量。
InstanceContextMode
所做的是控制执行
new Foo()
的频率

下面是一些显示差异的示例代码

public static Main()
{
    Console.WriteLine("1- PerCall");
    Console.WriteLine("2- Session");
    Console.WriteLine("3- Single");
    Console.Write("Choose: ");

    var choice = Console.ReadLine();

    switch(choice)
    {
        case "1":
            PerCallExample();
            PerCallExample();
            break;
        case "2":
            PerSessionExample();
            PerSessionExample();
            break;
        case "3":
            var foo = Foo();
            SingleExample(foo);
            SingleExample(foo);
            break;

    }
}

void Call(Foo foo)
{
    Console.WriteLine(foo.GetNumber());
}

void PerCallExample()
{
     Foo foo;

     foo = new Foo();
     Call(Foo foo);

     foo = new Foo();
     Call(Foo foo);
}

void PerSessionExample()
{
     Foo foo = new Foo();

     Call(Foo foo);
     Call(Foo foo);
}

void SingleExample(foo)
{
     Call(Foo foo);
     Call(Foo foo);
}
无论您选择什么,所有3种模式都将输出
1、2、3、4
。但是,如果您从
number
中删除
静态
,您应该从
PerCall
中获得
1、1、1、1
会话的
1、2、1、2
,以及
单个
1、2、3、4


现在将此应用于您的WCF。因为您的
列表
是静态的,所以在下次重新启动服务之前,它将在对您的服务的所有调用中共享,这就是您的数据被保留的原因。您需要将其更改为什么,而不是静态列表,我不能不知道您想要做什么(但是,将其从静态更改为实例上下文
Single
将产生与静态相同的效果,正如您在上面的示例中所看到的。因此,您可能也不想使用
Single
。)

非常感谢您的回答。我删除了静态关键字,@user3344394记住也要更改
InstanceContextMode
。并替换为PerSession,现在它可以正常工作了..谢谢。Liron。
public static Main()
{
    Console.WriteLine("1- PerCall");
    Console.WriteLine("2- Session");
    Console.WriteLine("3- Single");
    Console.Write("Choose: ");

    var choice = Console.ReadLine();

    switch(choice)
    {
        case "1":
            PerCallExample();
            PerCallExample();
            break;
        case "2":
            PerSessionExample();
            PerSessionExample();
            break;
        case "3":
            var foo = Foo();
            SingleExample(foo);
            SingleExample(foo);
            break;

    }
}

void Call(Foo foo)
{
    Console.WriteLine(foo.GetNumber());
}

void PerCallExample()
{
     Foo foo;

     foo = new Foo();
     Call(Foo foo);

     foo = new Foo();
     Call(Foo foo);
}

void PerSessionExample()
{
     Foo foo = new Foo();

     Call(Foo foo);
     Call(Foo foo);
}

void SingleExample(foo)
{
     Call(Foo foo);
     Call(Foo foo);
}