2

如果我运行我的 WCF 服务(托管在 II7 中)并在 contextinstance 上使用 PerSession,一个会话是否与一个线程相同?当客户端没有进行任何调用但在服务上有会话时会发生什么?会话是否仍在线程中?

如果我更改为 PerCall,我假设每次调用都会获得一个线程,并且在调用结束时会返回该线程。

我在哪里可以找到这些信息?

4

2 回答 2

3

我相信你可以在这里找到答案和很好的解释。

乍一看,您会出于可伸缩性原因使用 PerCall,而PerSession用于通常的 Web 场景。

  • 使用PerSession时,客户端第一次调用服务实现的实例将保留在服务器上。每个客户端都有自己的会话,每个客户端只在一个线程(!)上执行。所以,是的 1 Session == 1 Thread 默认情况下。但是您也可以更改ConcurrencyMode,因此在一个会话中客户端可以进行许多并发调用。

  • 如果是PerCall服务实例将在调用完成后立即处理。

[编辑(与大卫尼尔森讨论后)]:

(!)这并不意味着相同的线程!这只意味着 ThreadPool 将使用可用线程来运行服务代码。但是如果启动 1000 个并发客户端,ThreadPool 会分配很多线程,这涉及到资源,比如内存。

用代码解释线程使用:

我创建了简单的计算器服务来展示 WCF 服务是如何工作的。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorService
{
    private int _threadIdOnCreating = Thread.CurrentThread.ManagedThreadId;
    public int AccumulatedValue { get; private set; }
    public int Accumulate(int valueToAdd)
    {
        AccumulatedValue += valueToAdd;

        Console.WriteLine(
string.Format("Accumulated: {0}. ThreadIdOnServiceCreating:{1} CurrentThreadId:{2}",
            AccumulatedValue, _threadIdOnCreating, Thread.CurrentThread.ManagedThreadId));

        return AccumulatedValue;
    }
}

我使用参数 2 运行 Accumulate 方法五次,然后创建新的客户端代理并执行相同操作。下面是输出,证明服务器保留了服务实现的实例(创建时的threadId),但是方法在不同的线程上运行,取自ThreadPool。

I'm calculator
Accumulated: 2. ThreadIdOnServiceCreating:6 CurrentThreadId:6
Accumulated: 4. ThreadIdOnServiceCreating:6 CurrentThreadId:7
Accumulated: 6. ThreadIdOnServiceCreating:6 CurrentThreadId:6
Accumulated: 8. ThreadIdOnServiceCreating:6 CurrentThreadId:7
Accumulated: 10. ThreadIdOnServiceCreating:6 CurrentThreadId:6
Accumulated: 2. ThreadIdOnServiceCreating:9 CurrentThreadId:9
Accumulated: 4. ThreadIdOnServiceCreating:9 CurrentThreadId:6
Accumulated: 6. ThreadIdOnServiceCreating:9 CurrentThreadId:9
Accumulated: 8. ThreadIdOnServiceCreating:9 CurrentThreadId:6
Accumulated: 10. ThreadIdOnServiceCreating:9 CurrentThreadId:8
于 2012-04-03T20:46:41.830 回答
1

“如果我运行我的 WCF 服务(托管在 II7 中)并在 contextinstance 上使用 PerSession,一个会话是否与一个线程相同?

不,请求将由线程池处理。

“当客户端没有进行任何调用但在服务上有会话时会发生什么?会话是否仍在占用线程?”

不,如果没有服务请求,会话不会占用线程。WCF“会话”只是数据;状态绑定到会话 ID。它与线程无关。

于 2012-04-03T21:11:08.127 回答