双工Wcf服务应用程序,列出上次应用程序运行时的值

时间:2014-02-23 21:51:16

标签: c# wcf

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

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1 : IService1
{
    private static List<int> lst = new List<int>();
    public void Subscribe()
    {
          lst.Add(1);
          //....

奇怪的是,当我运行应用程序时,List&#39;记得&#39;从上次运行的价值.. 并且lst.Count从整个应用程序的完整不同运行中变得越来越大。 我无法找到原因。 我还尝试将InstanceContextMode设置为其他单个,但这没有帮助。 谢谢, Liron。

2 个答案:

答案 0 :(得分:0)

那是因为你正在使用静态字段,它在所有呼叫之间共享。

因为InstanceContextMode = InstanceContextMode.Single。它使您的服务以单一模式运行,这意味着只为您的所有客户端和连接创建了Service1类的一个实例。

  

只有一个InstanceContext对象用于所有来电,并且在通话后不会被回收。如果服务对象不存在,则创建一个服务对象。

     来自InstanceContextMode Enumeration

您可能应该使用InstanceContextMode.PerSession代替,并将您的字段更改为实例:

public class Service1 : IService1
{
    private List<int> lst = new List<int>();

答案 1 :(得分:0)

让我们把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。但是,如果您从static移除number,则应从1, 1, 1, 1获得PerCall1, 2, 1, 2获取Session1, 2, 3, 4获取Single List

现在将此应用于您的WCF。由于您的Single是静态的,因此在下次重新启动服务之前,它将在您的服务的所有调用之间共享,这就是您的数据被保留的原因。你需要改变它而不是一个静态列表我不能不知道你想要做什么(但是,将它改为静态并使其成为实例上下文Single将具有正如您在上面的示例中看到的那样,与静态相同的效果。因此您可能不想使用{{1}}。)