2

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

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

4

3 回答 3

1

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

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

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

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

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

希望这可以帮助马可

于 2012-08-10T06:51:12.943 回答
1

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

于 2012-08-10T16:43:36.373 回答
0

微软的另一个好资源:

并发管理

就我而言,我最终使用了基于服务类型的锁:

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

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

于 2016-12-12T16:37:53.770 回答