2012-08-10 52 views
2

我需要强制我的WCF服务在单个线程中运行,因为内部操作取决于不支持多线程调用的传统COM对象。如何强制WCF服务只使用一个线程?

然后我写了下面的示例代码,但如我所料:(

[ServiceContract] 
public interface ITestService 
{ 
    [OperationContract] 
    void TestAction(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode =  ConcurrencyMode.Single)] 
public class TestServiceImp : ITestService 
{ 
    void TestAction() 
    { 
     Trace.WriteLine("Entering method TestAction, Thread={0}" + Thread.CurrentThread.ManagedThreadId); 
     //... 
     Trace.WriteLine("Leaving method TestAction, Thread={0}" + Thread.CurrentThread.ManagedThreadId); 
    } 
} 

真正的结果是一样的东西下面,

进入它不工作方法TestAction,线程= 4

离开方法TestAction,线程= 4

输入方法TestAction,线程= 5

离开方法TestAction,线程= 5

输入方法TestAction,线程= 8

离开方法TestAction,线程= 8

虽然我的期望是,

输入方法TestAction,线程= 4

离开方法TestAction,线程= 4

输入方法TestAction,线程= 4

离开方法TestAction,线程= 4

进入方法TestAction,Thread = 4

保留方法TestAction,线程= 4

我怎么能得到我想要的东西?谢谢。

+0

我可以建议这个答案几乎相同的问题:[c# - 强制WCF使用一个线程 - Stack Overflow](http://stackoverflow.com/questions/20000078/force-wcf-to-use-one-线程/ 20010432#comment51204132_20010432) – 2015-07-25 16:11:57

回答

1

将InstanceContextMode声明为“Single”意味着来自不同客户端的每个调用都将在同一个实例上执行,但负责执行的线程由线程池管理。

基本上,如果你为每个调用使用并发模式“Single”(默认配置),一个线程将从线程池中取出,使用并返回给它,所以有可能线程是相同但不能保证

如果您想要管理对非线程安全资源的访问,您应该手动执行此操作,以定义哪个线程将执行您的服务实例,而不是使用 的SynchronizationContext

http://nevmehta.blogspot.ch/2006/12/what-is-usesynchronizationcontext.html

http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

希望这有助于 马尔科

+0

我明白了。非常感谢! – 2012-08-13 02:26:06

0

从微软的另一个很好的资源:

Concurrency Management

在我来说,我结束了使用基于服务类型的锁:

lock (typeof(MyServiceType)) { 
... 
} 

上设置单ConcurrencyMode时要小心使用EntityFramework上下文的WCF服务,因为服务及其资源在线程被终止之前不会被处理,最终会导致读取操作的未更新数据。