ECMA-335规范说明如下:
*获取锁(System.Threading.Monitor.Enter或输入同步方法)应隐式执行易失性读操作,释放锁(System.Threading.Monitor.Exit或保留同步方法)应隐式执行易失性写操作操作.(......)
易失性读取具有获取语义,这意味着保证在CIL指令序列中的读取指令之后发生的对存储器的任何引用之前发生读取.易失性写入具有释放语义,这意味着写入保证在CIL指令序列中的写入指令之前的任何存储器引用之后发生.*
这意味着编译器不能将语句移出Monitor.Enter/Monitor.Exit块,但不禁止其他语句移入块中.也许,甚至可以将另一个Monitor.Enter移动到块中(因为可以交换易失性写入,然后是易失性读取).那么,可以使用以下代码:
class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();
public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
}
public void B()
{
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
}
}
Run Code Online (Sandbox Code Playgroud)
,变成以下的等价物:
class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();
public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Enter(_locker2);
Monitor.Exit(_locker1);
//Do something
Monitor.Exit(_locker2);
}
public void B()
{
Monitor.Enter(_locker2);
//Do something …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用 System.Windows.Interactivity.Interaction 和来自 MS Expression Blend SDK for .NET 4 的 WPF。问题是我在那里找不到 Interaction.Triggers 附加属性。Interaction 类存在,但我只能看到其中有 4 个成员:Equals、GetBehaviors、GetTriggers、ReferenceEquals。我在我的项目中查看了 System.Windows.Interactivity.dll 引用的属性,发现路径是
“C:\Program Files (x86)\Microsoft SDKs\Expression\Blend.NETFramework\v4.0\Libraries\System.Windows.Interactivity.dll”
因此,我使用 IL Disass?mbler 打开该路径上的文件,发现交互类实际上具有 Triggers 附加属性,但该属性被声明为私有!然后我在 Prism SDK 的 \Lib\Desktop 目录中打开了相同的 dll 并在那里发现了相同的情况。这些 dll 的版本是 2.0.20525.0。还有一个带有 System.Windows.Interactivity dll 的 System.Windows.Interactivity.xml 文件。在其中,我发现了以下有关 TriggersProperty 的信息:
此属性不公开。这会强制客户端使用 GetTriggers 和 SetTriggers 方法来访问集合,确保集合存在并在使用之前设置。
但我没有在那里找到任何 SetTriggers 方法。顺便说一句,Silverlight 的交互将 TriggersProperty 作为公共成员。
我看过很多使用 Interaction.Triggers 和 WPF 的例子,我认为应该没有任何问题。我究竟做错了什么?