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