See http://blogs.microsoft.co.il/blogs/applisec/archive/2009/11/23/wcf-thread-affinity-and-synchronization.aspx.
It gives the following example, which seems to indicate that WCF completely breaks the lock keyword in C#:
public class MyService : IContract
{
//author of article originally did not initialize this in his illustration
//initializing it here so that we can avoid talking about side issues.
public static object wait_handle = new object();
public int LongOperation()
{
lock (wait_handle)
{
Before(); //Thread1 has the lock
LongWait(); //Threads might be switched here
After(); // Thread2 does not have the lock but
it runs.
return 0;
}
}
public int SecondOperation()
{
// If accidently Thread1 is allocated it has the handle and would enter the lock.
lock (wait_handle)
{
DoWork();
}
return 0;
}
}
This just seems like it would be a horrible decision on Microsoft's part, since it breaks the common usage of a keyword, and means that I can't reliably use any previously developed libraries of code from within WCF services unless I verify that they don't use "lock" in their code. (I presume that if the article is true, this means that the lock keyword uses some sort of thread-local type storage).
Did Microsoft really do this? Or am I missing something? Or is the referenced article inaccurate?
I think that the author of that article has misunderstood what a lack of thread affinity means within a WCF service. MSDN has an excerpt available from the book Programming WCF Services specifically relating to concurrency that would be worth reading through.
The short answer seems to be that, in a multi-call concurrency model, you cannot be assured that the thread you're using within a service has the required affinity that you're looking for (for example, if your thread requires use of thread-local storage or that it run on the UI thread). You can specifically set this through use of a SynchronizationContext, but once the service is entered the thread affinity for that call is locked down.
Incoming service calls execute on worker threads from the I/O completion thread pool and are unrelated to any service or resource threads. This means that by default the service cannot rely on any kind of thread affinity (that is, always being accessed by the same thread). Much the same way, the service cannot by default rely on executing on any host-side custom threads created by the host or service developers.
There is no reason that a thread under WCF might arbitrarily stop what it was doing, marshal over everything that it was currently doing and had access to and begin a new thread with that same context right in the middle of a call. That would highly dangerous and hardly provide the kind of scalability that the author claims this provides. Monitor.Enter() and the lock statement are perfectly acceptable to use within a WCF service provided that your code requires that level of synchronization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With