All*_*nek 17 c# lazy-loading visual-studio-2010 visual-studio visual-studio-debugging
我有一个带有一些静态属性的静态类.我在静态构造函数中初始化了所有这些,但后来意识到它是浪费的,我应该在需要时懒惰加载每个属性.所以我切换到使用该System.Lazy<T>类型来完成所有脏工作,并告诉它不要使用它的任何线程安全功能,因为在我的情况下执行始终是单线程的.
我最后得到了以下课程:
public static class Queues
{
private static readonly Lazy<Queue> g_Parser = new Lazy<Queue>(() => new Queue(Config.ParserQueueName), false);
private static readonly Lazy<Queue> g_Distributor = new Lazy<Queue>(() => new Queue(Config.DistributorQueueName), false);
private static readonly Lazy<Queue> g_ConsumerAdapter = new Lazy<Queue>(() => new Queue(Config.ConsumerAdaptorQueueName), false);
public static Queue Parser { get { return g_Parser.Value; } }
public static Queue Distributor { get { return g_Distributor.Value; } }
public static Queue ConsumerAdapter { get { return g_ConsumerAdapter.Value; } }
}
Run Code Online (Sandbox Code Playgroud)
在调试时,我注意到了一条我从未见过的消息:
功能评估需要运行所有线程

使用前Lazy<T>,直接显示值.现在,我需要单击带有线程图标的圆形按钮来评估惰性值.这只发生在检索.Valueof的我的属性上Lazy<T>.展开实际Lazy<T>对象的调试器可视化器节点时,该Value属性只显示null,没有任何消息.
这条消息意味着什么,为什么它会在我的案例中显示出来?
All*_*nek 15
我找到了一个MSDN页面标题为" 如何:刷新监视值 "解释它:
在调试器中计算表达式时,"值"列中可能会显示两个刷新图标之一.一个刷新图标是一个包含两个箭头的圆圈,它们以相反的方向圈出.另一个是一个圆圈,包含两条类似于线的波浪线.
...
如果出现两个线程,则由于潜在的跨线程依赖性而未评估表达式.跨线程依赖性意味着评估代码需要应用程序中的其他线程临时运行.处于中断模式时,应用程序中的所有线程通常都会停止.允许其他线程临时运行会对程序的状态产生意外影响,并导致调试器忽略断点等事件.
如果有人能提供,我仍然想要更好的解释.这个问题没有回答的问题包括:什么样的评估需要所有线程运行?调试器如何识别这种情况?单击线程刷新图标时会发生什么?
编辑:我认为Lazy<T>在ILSpy下进行检查时我偶然发现了答案(完全不同的原因).酒店的吸气者Value打电话给Debugger.NotifyOfCrossThreadDependency().MSDN有这样的说法:
[...]执行功能评估通常需要冻结除执行评估的线程之外的所有线程.如果函数评估需要在多个线程上执行(如远程方案中可能发生的那样),则评估将阻止.NotifyOfCrossThreadDependency通知通知调试器它必须释放线程或中止功能评估.
所以基本上,为了防止你尝试评估某个表达式的烦人情况,Visual Studio只挂起30秒,然后通知你"函数评估已经超时",代码有机会通知调试器它必须解冻评估成功的其他线程,否则评估将永远阻止.
由于运行其他线程可能会破坏您的调试会话,因为通常在评估表达式时,所有其他线程都保持冻结状态,调试器不会自动执行并在让您跳下兔子洞之前发出警告.
| 归档时间: |
|
| 查看次数: |
25471 次 |
| 最近记录: |