我正在探索WCF实例上下文模式和并发性的更多细节,并对BasicHttpBinding和WSHttpBinding的托管threadID值感到困惑。
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
public class Service2 : IService1
{
int i;
public string GetData(int value)
{
string output = string.Format("Service2 {0} , {1} , {2}",
DateTime.Now.ToString(),
i++,
System.Threading.Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(output);
System.Threading.Thread.Sleep(5000);
return output;
}
}
样品测试
public class program
{
[STAThread]
public static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service2),
new Uri("http://localhost:9011"),
new Uri("net.tcp://localhost:9009"));
host.AddServiceEndpoint(typeof(IService1),
new BasicHttpBinding(), "");
host.AddServiceEndpoint(typeof(IService1),
new WSHttpBinding(), "WS");
Test1();
Console.WriteLine("-------------------------------");
Test2();
Console.WriteLine("-------------------------------");
Console.ReadLine();
}
public static void Test1()
{
EndpointAddress endPoint = new EndpointAddress("http://localhost:9011");
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<IService1> client = new ChannelFactory<IService1>(binding, endPoint);
IService1 proxy = client.CreateChannel();
Enumerable.Range(1, 10).ToList().ForEach(cc =>
{
proxy.GetData(10);
});
}
public static void Test2()
{
EndpointAddress endPoint = new EndpointAddress("http://localhost:9011/WS");
WSHttpBinding binding = new WSHttpBinding();
ChannelFactory<IService1> client = new ChannelFactory<IService1>(binding, endPoint);
IService1 proxy = client.CreateChannel();
Enumerable.Range(1, 10).ToList().ForEach(cc =>
{
proxy.GetData(10);
});
}
}
现在问题在于ManagedThreadId。
如果查看Test1()的输出,那么所有10的ManagedThreadId值都相同。
但是如果你看一下Test2()那么ManagedThreadId值是不同的。
为什么会这样?
答案 0 :(得分:0)
InstanceContextMode
和ConcurrencyMode
本质上是一个抽象层,它控制服务对象的实例生命周期以及如何对其进行序列化(如果有)和不描述线程模型,以确定是否使用相同的线程。
如果我们看一下你的例子:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
......这基本上是设置线程安全的;单身人士服务。对于单模并发,所有调用都排队并一次执行一个。 1
在我的阅读和经验中,虽然WCF没有说明哪个线程将用于上述属性,但WCF与不同的自定义线程同步上下文兼容虽然这样的实现有:
“......与WCF无关”;洛伊,1
OP:
如果查看Test1()的输出,那么所有10的ManagedThreadId值都相同。
但是如果你看一下Test2()那么ManagedThreadId值是不同的
我会说你看到的所有内容都可能是BasicHttpBinding
下的默认服务行为是使用自定义线程池同步器,其中调用排队并依次在相同的线程上执行而在WSHttpBinding
下使用默认线程池(因此线程不同的原因)。