为什么我总是得到改变线程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 ?

为什么我总是得到改变线程Id时,托管在另一个线程与wcf

在另一个线程上启动服务,但是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);
    }
}