我有一个对象启动一个线程,打开一个文件,并等待来自其他类的输入.当它接收输入时,它会将其写入磁盘.基本上,它是一个线程安全的数据记录类...
这是奇怪的部分.当我在设计器(Visual Studio 2008)中打开一个使用该对象的表单时,将创建该文件.它显然是在设计时vhost进程下运行的......
奇怪的是我无法在另一个项目中重现这个问题.我不确定在设计器中执行的代码和没有执行的代码的规则是什么.例如,在Windows窗体构造函数中创建文件实际上并不是在设计时创建文件...
解释是什么?有参考吗?
在设计器中编辑该类时,控件或表单的构造函数不会被执行(OnLoad也不会被调用).我偶尔使用它在设计器中设置一个值(例如,使其子控件在设计器中都是可见的),但是将其中的一些值覆盖到构造函数中的不同默认值(例如,隐藏某些仅显示的子控件)在某些情况下,例如状态栏上的指示器).
但是,如果将控件作为子项放置在设计器中的另一个控件或窗体上,则构造函数会执行.OnLoad也被执行了.这可能是您的日志记录代码在设计器中意外触发的方式.
为了检测设计VS运行时,一个答案到另一个问题具有一些emperical测试示出了由一些共同的方法返回的值截屏.看起来设计器中正在编辑的表单或控件的子控件(两级向下)的子控件看到自己的DesignMode == false,因此正常的属性检查将无法保护代码(例如,在OnLoad方法中) )嵌套在设计器中添加的控件中的控件.如果您按照预期检查DesignMode,则可能是嵌套导致它绕过该检查.它也始终在构造函数中看到DesignMode == false.
另请注意,LicenseManager.UsageMode检查仅在构造函数中看到DesignTime; 当调用OnLoad时,它位于RunTime LicenseContext中.最完整的解决方案似乎是检查控件或表单(或组件)的构造函数中的LicenseManager.UsageMode,并将设置保存到成员变量或属性,稍后可以检查以避免运行永远不会在设计器中运行的代码甚至在嵌套时.在另一个问题的另一个答案中还有另一种方法可以解释嵌套,但只能在构造函数之外工作.
您可以检查LicenseManager的UsageMode,以检查代码是否在设计时间内.
System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime
这是一个简单的例子:
using System; using System.ComponentModel; using System.Windows.Forms; namespace Test { public class ComponentClass : Component { public ComponentClass() { MessageBox.Show("Runtime!"); } } }
当此组件添加到设计器中的表单时,您将立即获得一个消息框.
为了防止这种情况,您可以添加一个简单的if语句来检查代码是否不在设计时
using System; using System.ComponentModel; using System.Windows.Forms; namespace Test { public class ComponentClass : Component { public ComponentClass() { if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) { MessageBox.Show("Runtime!"); } } } }
添加if语句后,通过设计器将组件添加到表单时,不再显示消息框.
我希望这有帮助.
-jeremy