在我的应用程序中,我托管 WCF服务:
private void StartService()
{
m_serviceHost = new ServiceHost(typeof(...));
m_serviceHost.Open();
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(StartService);
t.IsBackground = true;
t.Start();
// ...
}
服务本身只有一种方法:
public void SendMessage(string message)
{
MessageBox.Show(String.Format("Message '{0}' received on thread {1} : MessageLoop =
{2}", message, Thread.CurrentThread.GetHashCode(), Application.MessageLoop),
"MessagingService.SendMessage()");
}
当客户端调用此操作时,我得到以下响应:
Message 'hello client : message 9 recieved on thread **12**
Message 'hello client : message 9 recieved on thread **15**
Message 'hello client : message 9 recieved on thread **17**
...
为什么线程ID总是会改变?当我创建ServiceHost时,我只把他放在另一个线程上! 我不是每次都把他放在另一个主题上...只有一次
如何将主机放在另一个线程中(就像我做的那样)并且只获得单个后台线程ID?
答案 0 :(得分:2)
您在另一个线程上启动服务,但ServiceHost本身使用多个线程来处理请求。
如果您的服务不是线程安全的,您可以通过使用ServiceBehaviorAttribute
修改服务类并将ConcurrencyMode
设置为Single
来强制以单线程方式执行它:< / p>
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class ServiceClass
{
}
答案 1 :(得分:1)
IIRC正确地说ConcurrencyMode.Single并不保证使用单个线程...它保证只有一个线程可以访问服务实例...从而防止了两个(或更多)线程可能产生的并发问题使用相同的服务实例(状态可能会被破坏)。
我想你想强制执行一个线程来处理所有调用,所以一切都按顺序完成,没有任何状态被破坏。但是使用默认的InstanceContextMode(PerCall),每个调用都会获得自己的服务实例。并且将ConcurrencyMode设置为single,您确定只有一个线程访问服务实例。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
InstanceContextMode = InstanceContextMode.PerCall)]
public class MessageService : IMessageService
{
public string ReturnMessage()
{
return String.Format("Thread {0}", Thread.CurrentThread.ManagedThreadId);
}
}