为什么我总是得到改变线程Id时,托管在另一个线程与wcf
本文关键字:线程 wcf 另一个 Id 改变 为什么 | 更新日期: 2023-09-27 18:08:57
在我的应用程序中我主机一个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 ?
您在另一个线程上启动服务,但是ServiceHost本身使用多个线程来处理请求。
如果你的服务不是线程安全的,你可以强迫它以单线程的方式执行,通过用ServiceBehaviorAttribute
装饰服务类,并将ConcurrencyMode
设置为Single
:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class ServiceClass
{
}
正确设置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);
}
}