【发布时间】:2022-07-26 12:57:10
【问题描述】:
我创建了一个 WCF 服务,并希望被多个 VB 客户端使用。
我只需要一个服务实例,即使有多个客户端启动、使用或停止。
但结果似乎出乎我的意料。 我的代码是:
WCF 服务:
namespace xComm
{
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
public class SvcACS : ISvcACS
{
private int m_nCounter = 0;
public int CounterUp()
{
m_nCounter++;
return m_nCounter;
}
public int CounterGet()
{
return m_nCounter;
}
}
}
构建WCF服务后,我可以通过VB应用程序的COM引用来使用它,如下图,一个简单的表单应用程序调用CountUp方法并检查返回值:
Option Explicit
Dim svcAcs As xComm.ISvcACS
Private Sub btnCmd_Click(Index As Integer)
Dim nW1 As Integer
nW1 = svcAcs.CounterUp()
lblCounter.Caption = CStr(nW1)
End Sub
Private Sub Form_Load()
Set svcAcs = New xComm.svcAcs
End Sub
例如,我启动了 2 个 VB 客户端并分别按下 btnCmd 按钮。 我想要的是:
- 客户端 1 的 btnCmd 被点击:客户端 1 的 lblCount 显示 1
- 客户端 2 的 btnCmd 被点击:客户端 2 的 lblCount 显示 2
- 客户端 1 的 btnCmd 被点击:客户端 1 的 lblCount 显示 3 ...
但结果证明,客户端是独立服务的,而不是使用单个服务实例,而计数器本来是共享的。
我用过InstanceContextMode.Single,这还不够吗?
提前致谢。
婷
一些新发现(2022/7/26):
我没有直接使用COM引用,而是尝试了下面的VB代码:
Dim Client As New MSSOAPLib30.SoapClient30
Set Client = CreateObject("MSSOAP.SoapClient30") 'xcomm.svcACS")
Call Client.mssoapinit("http://localhost:8733/SvcACS?wsdl")
'localhost:8733/SvcACS" binding="basicHttpBinding"
MsgBox (Client.CounterUp())
结果显示多个 VB 应用程序实例使用同一个服务实例。
而且我还使用 SvcUtilexe 生成的客户端代码测试了 C# 客户端,结果显示相同。
但在这两种情况下,将 InstanceContextMode 更改为 PerCall 或 PerSession 没有区别。
我猜,可能是自托管服务的行为,主动服务对所有人都有效。
但我仍然不明白 COM 接口是如何工作的。貌似使用COM接口,每次都会创建一个新的服务实例。
【问题讨论】: