【问题标题】:How to force WCF service use only one thread?如何强制 WCF 服务只使用一个线程?
【发布时间】:2016-12-13 00:37:53
【问题描述】:

由于内部操作依赖于不支持多线程调用的旧 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,Thread=4

离开方法TestAction,Thread=4

进入方法TestAction,Thread=5

离开方法TestAction,Thread=5

进入方法TestAction,Thread=8

离开方法TestAction,Thread=8

虽然我的期望是,

进入方法TestAction,Thread=4

离开方法TestAction,Thread=4

进入方法TestAction,Thread=4

离开方法TestAction,Thread=4

进入方法TestAction,Thread=4

离开方法TestAction,Thread=4

我怎样才能得到我想要的?谢谢。

【问题讨论】:

标签: wcf


【解决方案1】:

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

基本上,如果您对每个调用使用并发模式“Single”(默认配置),则线程将从线程池中获取,使用然后返回给它,因此线程可能是相同的但不能保证

如果您想管理对非线程安全资源的访问,您应该手动进行,要定义哪个线程将执行您的服务实例,您必须使用 同步上下文

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

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

希望这会有所帮助 马可

【讨论】:

    【解决方案2】:

    查看Synchronization Contexts in WCF 中描述的线程关联同步上下文。

    【讨论】:

      【解决方案3】:

      来自 Microsoft 的另一个好资源:

      Concurrency Management

      在我的情况下,我最终使用了基于服务类型的锁:

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

      在使用 EntityFramework 上下文的 WCF 服务上设置 Single ConcurrencyMode 时要小心,因为在线程被杀死之前不会释放服务及其资源,这可能会导致读取操作中的数据未更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        相关资源
        最近更新 更多