WCF并发模式Single和实例上下文模式PerCall

21
我有一个关于WCF服务配置的问题。 我希望每次调用我的服务都会创建一个新的服务实例。 对于并发性,我希望在一个调用完成之前不会启动另一个调用。
因此,如果我的服务如下所示:
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single,
InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService: IMyService
{
    public bool MyServiceOp()
    {
        Debug.WriteLine("thread "+ 
            Thread.CurrentThread.ManagedThreadId.ToString());
        Debug.WriteLine("start operation ");
        Do_work()
        Debug.WriteLine("end operation");
        return true;
    }
}

在我用循环多次调用它时,跟踪结果如下:

thread 1
thread 2
start operation
start operation
end operation
end operation

虽然我希望拥有这个:

thread 1 start operation end operation
thread 2 start operation end operation

这个可能吗?谢谢


3
如果您想在不同的服务调用之间像您描述的那样同步线程,唯一的方法是将服务配置为并发性和实例上下文都设置为单个(即单例模式)。如果这样做,您的应用程序几乎没有可扩展性,因为您正在创建一个非常有效率的瓶颈。 - Sixto Saez
1
@Sixto:并发性和上下文生命周期是两个不同的概念。不需要使用单例模式。 - ErnieL
2个回答

21

我知道这个问题已经被标记为已回答,但是有更好的替代方案:

如果您使用的是 InstanceContextMode.Single,则对于所有调用将重用同一实例。如果您的服务运行时间较长,这就要求您的代码完美地管理资源,因为它将永远不会在没有服务重新启动的情况下进行垃圾回收。

相反,保持 InstanceContextMode.PerCall,“每次对我的服务的调用都创建一个新实例”,然后使用限流:最大并发实例数设置为 1。 MSDN文档正是通过一个示例来实现这一点。


5

您所拥有的代码会在每个请求时启动一个新的服务实例(这就是PerCall的作用)。

以下代码可以解决这个问题:

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single, InstanceContextMode=InstanceContextMode.Single)]

请注意,如果您这样做,将会失去所有的可扩展性。您将只有一个单线程服务实例来响应所有请求。


1
这是否满足OP中指定的要求:“我希望每次调用我的服务都创建一个新的服务实例”? - Merlyn Morgan-Graham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接