Why do i always get changed Thread Id when hosting on another thread with wcf?
In my application I host a WCF service:
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();
// ...
}
The service itself has just one method:
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()");
}
When the client calls this operation I get the following responses:
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 thr开发者_如何学Cead **17**
...
Why does the thread id always change? When I created the ServiceHost I only put him on another thread! im not re-putting him on another thread each time... only once
How can i put the host in another thread (like i did) and to get only single background thread id ?
You started the service on another thread, but the ServiceHost itself uses multiple threads to process requests.
If your service is not thread safe, you can force it to be executed in a single threaded manner by decorating the service class with a ServiceBehaviorAttribute
and setting ConcurrencyMode
to Single
:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class ServiceClass
{
}
IIRC correctly the ConcurrencyMode.Single does not guarantee that a single thread is used...it guarantees that only a single thread can access the service instance...thus preventing concurrency issues that might arrise if two (or more) threads use the same service instance (state might get corrupted for instance).
I guess you want to enforce one thread to handle all the calls so everything gets done sequentially and no state gets corrupted. But with the default InstanceContextMode (PerCall) each call gets its own service instance anyway. And with the ConcurrencyMode set to single you are sure that only one thread accesses a service instance.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
InstanceContextMode = InstanceContextMode.PerCall)]
public class MessageService : IMessageService
{
public string ReturnMessage()
{
return String.Format("Thread {0}", Thread.CurrentThread.ManagedThreadId);
}
}
精彩评论