为什么一个代码路径会立即在顶部显示表单,而另一个代码路径则不会
本文关键字:代码 路径 表单 显示 另一个 顶部 一个 为什么 | 更新日期: 2023-09-27 18:05:31
我正在维护一个使用Castle Windsor作为框架的c# .net程序。它还使用Skincrafter来装饰窗体。
在其中,我们有检测USB设备上文件存在的功能,并产生另一种形式来处理它。当Windows引发USB事件或当用户按下强制重新检查的按钮时,软件检查文件。
当用户强制重新检查时,如果找到该文件,则该表单将出现在主表单的顶部,并由Skincrafter进行装饰。如果USB事件被触发,则生成表单,但不会出现在顶部(必须在任务栏中单击它才能看到它),并且不会由Skincrafter装饰。
检测文件的两种方法都到达同一个函数,该函数告诉程序的另一部分生成处理该文件的表单。我在调试时发现的唯一区别是,强制重新检查方法使用主线程,而USB事件方法有它自己的子线程,通过正在显示的表单。
是单独的线程,导致Windows不产生窗体在顶部(大概被Skincrafter忽略)或可能有一些其他问题?
如果需要,我可以发布代码,但是代码路径是相同的,除了调用文件检查的方法和数据是相同的。
编辑代码:
这是我生成的一个简单重构。新的WinForms项目与系统。管理层增加了参考资料。只需创建一个带有按钮的表单(FormStartPosition设置为CenterScreen),并使用以下代码:
public partial class Form1 : Form
{
private ManagementEventWatcher _eventWatcher = null;
int devices = 0;
public Form1()
{
InitializeComponent();
WqlEventQuery q = new WqlEventQuery();
q.EventClassName = "__InstanceOperationEvent";
q.WithinInterval = new TimeSpan(0, 0, 3);
q.Condition = @"TargetInstance ISA 'Win32_USBControllerDevice' ";
_eventWatcher = new ManagementEventWatcher(q);
_eventWatcher.EventArrived += new EventArrivedEventHandler(UsbEventArrived);
_eventWatcher.Start(); // Start listen for events
}
private void UsbEventArrived(object sender, EventArrivedEventArgs e)
{
if(System.Environment.GetLogicalDrives().Length - devices != 0) {
ShowThingy();
devices = System.Environment.GetLogicalDrives().Length;
}
}
private void button1_Click(object sender, EventArgs e)
{
ShowThingy();
}
private void ShowThingy()
{
Form form2 = new Form();
form2.Size = new Size(50, 50);
form2.StartPosition = FormStartPosition.CenterParent;
form2.TopMost = true;
form2.ShowDialog();
}
}
运行并插入USB设备,form2表单将出现在主表单后面。
这似乎不会每次都重现问题。但我第一次插入USB设备时,似乎总是在第一个设备后面创建第二个形式。每次单击按钮都会生成顶部的第二个表单。
您没有为模态窗口设置所有者,并且默认为活动窗口(可能不是您的主窗口)。
如果使用带有所有者的ShowDialog重载会发生什么?
form2.ShowDialog(this);
如果这不起作用,那就很有可能是线程问题。您可以尝试更改USB事件处理程序,以在窗体上使用Invoke吗?