ContextBoundObject and [Synchronization]: what calls are from another context? -
11-18-2007
, 11:02 AM
I tried asking this question with a slightly different phrasing before, but
have got no answers here on in the forums, so I thought I'd try again. My
understanding is that calls to ContextBoundObjects are checked to see
whether the caller is from the same context, and if not, the context rules
determine how the call is made. For objects with the [Serializable]
attribute, the context rules make sure that the caller holds some kind of
synchronization object (monitor/mutex/whatever) to ensure that only one
caller at a time can access objects in the context.
It seems to me, however, that some calls, that I thought would come from
another context indeed do not, and are not subject to synchronization. The
example code at the end of this message illustrates this. As it is, the
program outputs "Enter, Exit, Enter, Exit" in that order, which "proves"
that the calls to TestMethod are indeed protected by a lock.
However, if I replace the "new Thread(...).Start()" call by the line above
it (i.e., remove that comment for that line, and instead comment out the new
Thread() call), TestMethod is run twice concurrently.
I thought that BeginInvoke would use a background thread to call the method,
and that the calls would come from another context, thus having to take the
context lock before proceeding.
Can someone please explain what I'm missing here? I'm trying to enclose a
few classes in a server in a synchronization domain, in order to simplify
its implementation. At the moment, I use lock(someObject) for all of the
classes, where someObject is distributed during object construction, to have
all the objects lock on the same object. It seems to me synchronization
domains were invented in order not to have to do this manually.
So, I guess another way to phrase my question is: how do I make sure calls
from other objects come from different contexts so that the locking rules
apply?
Staffan
using System;
using System.Runtime.Remoting.Contexts;
using System.Threading;
namespace SyncTest
{
[Synchronization]
class Program : ContextBoundObject
{
static void Main(string[] args)
{
Program p = new Program();
p.Inside();
Console.ReadLine();
}
void Inside()
{
for (int i = 0; i < 2; i++)
{
//new TestDelegate(this.TestMethod).BeginInvoke(null, null);
new Thread(TestMethod).Start();
}
}
public delegate void TestDelegate();
public void TestMethod()
{
Console.WriteLine("Enter");
Thread.Sleep(1000);
Console.WriteLine("Exit");
}
}
} |