如果我运行我的 WCF 服务(托管在 II7 中)并在 contextinstance 上使用 PerSession,一个会话是否与一个线程相同?当客户端没有进行任何调用但在服务上有会话时会发生什么?会话是否仍在线程中?
如果我更改为 PerCall,我假设每次调用都会获得一个线程,并且在调用结束时会返回该线程。
我在哪里可以找到这些信息?
我相信你可以在这里找到答案和很好的解释。
乍一看,您会出于可伸缩性原因使用 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
“如果我运行我的 WCF 服务(托管在 II7 中)并在 contextinstance 上使用 PerSession,一个会话是否与一个线程相同?
不,请求将由线程池处理。
“当客户端没有进行任何调用但在服务上有会话时会发生什么?会话是否仍在占用线程?”
不,如果没有服务请求,会话不会占用线程。WCF“会话”只是数据;状态绑定到会话 ID。它与线程无关。