在Visual Studio中,当应用程序在调试模式下停止时,您可以将鼠标悬停在对象/属性上以查看其内部内容。
当您像我在上面的图片中所做的那样使用调试器打开对象时,属性将调用其Get方法作为调试器检索属性值以向用户显示的一种方式。
在我的应用程序中,我在我的Get访问器中添加了一个Debug.Assert()调用,以确保在此示例中的Foo已被锁定。每当我的代码调用Bar时,按设计,foo应该被锁定,但是当调试器尝试查看bar时,foo将不会被锁定,这意味着断言应该失败。
当调试器遇到失败的断言时,它有时会抑制断言弹出窗口,而其他时候则会显示与正常失败断言行为相同的断言弹出窗口。据我所知,Assert弹出窗口似乎被抑制了1-2次,但在那些第一次1-2次之后,每次都允许弹出窗口显示。虽然这是断言抑制的最常见行为,但并非总是如此,因为在应用程序的其他运行中,调试器从未停止抑制,无论调试器查看Bar多少次。
问题:对于我的应用程序,期望的行为是100%地抑制断言。我该如何实现这一点?
编辑:此外,如果调试器遇到其中一个断言并且失败,则会将下面的消息写入调试输出。无论是否抑制断言,这都是完全相同的消息。
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
foo.MyLock.EnterWriteLock();
foo.Bar = 5.1;
foo.MyLock.ExitWriteLock();
// "I stop here and attempt to see what the value of Bar is via the debugger."
foo.MyLock.EnterReadLock();
Console.WriteLine(foo.Bar);
foo.MyLock.ExitReadLock();
}
}
class Foo
{
private double bar;
public double Bar
{
get
{
Console.WriteLine(MyLock.IsReadLockHeld);
Debug.Assert(MyLock.IsReadLockHeld, "Please enter the read lock before attempting to read this property.");
return bar;
}
set
{
Debug.Assert(MyLock.IsWriteLockHeld, "Please enter the write lock before attempting to write this property.");
bar = value;
}
}
public ReaderWriterLockSlim MyLock { get; set; }
public Foo()
{
MyLock = new ReaderWriterLockSlim();
}
}
在我的应用程序中,我在我的Get访问器中添加了一个Debug.Assert()调用,以确保在此示例中的Foo已被锁定。每当我的代码调用Bar时,按设计,foo应该被锁定,但是当调试器尝试查看bar时,foo将不会被锁定,这意味着断言应该失败。
当调试器遇到失败的断言时,它有时会抑制断言弹出窗口,而其他时候则会显示与正常失败断言行为相同的断言弹出窗口。据我所知,Assert弹出窗口似乎被抑制了1-2次,但在那些第一次1-2次之后,每次都允许弹出窗口显示。虽然这是断言抑制的最常见行为,但并非总是如此,因为在应用程序的其他运行中,调试器从未停止抑制,无论调试器查看Bar多少次。
问题:对于我的应用程序,期望的行为是100%地抑制断言。我该如何实现这一点?
编辑:此外,如果调试器遇到其中一个断言并且失败,则会将下面的消息写入调试输出。无论是否抑制断言,这都是完全相同的消息。
---- DEBUG ASSERTION FAILED ----
---- Assert Short Message ----
Please enter the read lock before attempting to read this property.
---- Assert Long Message ----
at TestApp_Debugging.Foo.get_Bar() in c:\Users\Adrian.vanBerkhout\Documents\Visual Studio 2013\Projects\TestApp_Debugging\TestApp_Debugging\Program.cs:line 37
at TestApp_Debugging.Program.Main(String[] args) in c:\Users\Adrian.vanBerkhout\Documents\Visual Studio 2013\Projects\TestApp_Debugging\TestApp_Debugging\Program.cs:line 17
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
using(foo.AcquireReaderLock()) { DoSomething(foo.Bar) }
,而不会暴露锁本身。我喜欢完全内部的锁定机制的想法,但是当用户想要执行某种非原子操作时(例如if (foo.GetBar() > 10) { foo.SetBar(0); }
),该怎么办?如果所有的锁定机制都隐藏在 foo 内部,则会创建竞争条件。 - Adrian773