我需要强制我的WCF服务在单个线程中运行,因为内部操作取决于不支持多线程调用的旧COM对象。
然后我编写了以下示例代码,但它没有按预期工作:(
[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
我怎么能得到我想要的东西?感谢。
答案 0 :(得分:1)
将InstanceContextMode的服务声明为“Single”只意味着来自不同客户端的每个调用都将在同一个实例上执行,但负责执行的线程由线程池管理。
基本上如果你为每个调用使用并发模式“Single”(默认配置),线程将从线程池获取,使用然后返回给它,因此线程可能是相同的但无法保证
如果你想管理对非线程安全资源的访问,你应该手动完成,要定义哪个线程将执行你的服务实例,你需要使用 的SynchronizationContext
http://nevmehta.blogspot.ch/2006/12/what-is-usesynchronizationcontext.html
http://msdn.microsoft.com/en-us/magazine/gg598924.aspx
希望这会有所帮助 马可
答案 1 :(得分:1)
查看Synchronization Contexts in WCF中描述的线程亲和同步上下文。
答案 2 :(得分:0)
Microsoft的另一个好资源:
在我的情况下,我最终使用了基于服务类型的锁:
lock (typeof(MyServiceType)) {
...
}
在使用EntityFramework上下文的WCF服务上设置Single ConcurrencyMode时要小心,因为服务及其资源不会被释放,直到线程被终止,什么可能最终导致读取操作的非更新数据。 / p>