另一个具体示例:
class Program
{
public class Test
{
public string DoThis()
{
lock (this)
{
return "got it!";
}
}
}
public delegate string Something();
static void Main(string[] args)
{
var test = new Test();
Something call = test.DoThis;
IAsyncResult async;
lock (test)
{
async = call.BeginInvoke(null, null);
}
async.AsyncWaitHandle.WaitOne();
string result = call.EndInvoke(async);
lock (test)
{
async = call.BeginInvoke(null, null);
async.AsyncWaitHandle.WaitOne();
}
result = call.EndInvoke(async);
}
}
在此示例中,第一个调用将成功,但是如果在调试器中进行跟踪,则对DoSomething的调用将一直阻塞,直到释放锁定为止。第二个调用将死锁,因为主线程将监视器锁定保持为test。
问题是Main可以锁定对象实例,这意味着它可以阻止实例执行对象认为应该同步的任何事情。关键是对象本身知道需要锁定的内容,而外部干扰只是自找麻烦。这就是为什么拥有专用于您的同步的私有成员变量而不必担心外部干扰的模式的原因。
等效的静态模式也是如此:
class Program
{
public static class Test
{
public static string DoThis()
{
lock (typeof(Test))
{
return "got it!";
}
}
}
public delegate string Something();
static void Main(string[] args)
{
Something call =Test.DoThis;
IAsyncResult async;
lock (typeof(Test))
{
async = call.BeginInvoke(null, null);
}
async.AsyncWaitHandle.WaitOne();
string result = call.EndInvoke(async);
lock (typeof(Test))
{
async = call.BeginInvoke(null, null);
async.AsyncWaitHandle.WaitOne();
}
result = call.EndInvoke(async);
}
}
使用私有静态对象而不是Type进行同步。