c# EventArrivedEventHandler陷入无限循环,无法引用观察者

发布于 2024-12-03 00:08:47 字数 2630 浏览 0 评论 0原文

过去一周我一直在谷歌上搜索这个问题,它破坏了我的平静!请帮助... EventArrivedEventHandler 陷入循环,如果我停止它,它就不会捕获事件。但是当我使用处理程序方法时,线程仍然专注于循环,并且不会关注我试图在处理程序中创建的新表单!奇怪的是,如果我只使用一些小东西,比如 MessageBox,它不会引起问题,只是尝试实例化一个表单会导致按钮不绘制。然后程序停止响应后不久。如果您想知道表单代码在哪里,它只是 .NET 制作的标准表单,可以在代码中除事件处理程序之外的其他任何地方工作。

谢谢!

class MainClass
{
    public static void Main()
    {
        TaskIcon taskbarIcon;
        EventWatch myWatcher;

        taskbarIcon = new TaskIcon();
        taskbarIcon.Show();

        myWatcher = new EventWatch();
        myWatcher.Start();

        Application.Run();
    }
}

public class TaskIcon
{
    public void Show()
    {
        NotifyIcon notifyIcon1 = new NotifyIcon();
        ContextMenu contextMenu1 = new ContextMenu();
        MenuItem menuItem1 = new MenuItem();
        MenuItem menuItem2 = new MenuItem();

        contextMenu1.MenuItems.AddRange(new MenuItem[] { menuItem1, menuItem2 });

        menuItem1.Index = 0;
        menuItem1.Text = "Settings";
        menuItem1.Click += new EventHandler(notifyIconClickSettings);

        menuItem2.Index = 1;
        menuItem2.Text = "Exit";
        menuItem2.Click += new EventHandler(notifyIconClickExit);

        notifyIcon1.Icon = new Icon("app.ico");
        notifyIcon1.Text = "Print Andy";
        notifyIcon1.ContextMenu = contextMenu1;
        notifyIcon1.Visible = true;
    }

    private static void notifyIconClickSettings(object Sender, EventArgs e)
    {
        MessageBox.Show("Settings Here");
    }

    private static void notifyIconClickExit(object Sender, EventArgs e)
    {
        //taskbarIcon.Visible = false; // BONUS QUESTION: Why can't I hide the tray icon before exiting?

        Application.Exit();
    }
}

public class EventWatch
{
    public void Start()
    {
        string thisUser = WindowsIdentity.GetCurrent().Name.Split('\\')[1];

        WqlEventQuery query = new WqlEventQuery();

        query.EventClassName = "__InstanceCreationEvent";
        query.Condition = @"TargetInstance ISA 'Win32_PrintJob'";
        query.WithinInterval = new TimeSpan(0, 0, 0, 0, 1);

        ManagementScope scope = new ManagementScope("root\\CIMV2");
        scope.Options.EnablePrivileges = true;

        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);

        watcher.EventArrived += new EventArrivedEventHandler(showPrintingForm);

        watcher.Start();
    }
    void showPrintingForm(object sender, EventArrivedEventArgs e)
    {
        // MessageBox.Show("This will draw just fine");

        Form1 myForm;
        myForm = new Form1();
        myForm.Show(); // This causes a hangup
    }
}

I've googled this problem for the past week, it's killing my peace! Please help... EventArrivedEventHandler is stuck in a loop, and if I stop it, then it won't catch events. But when I use a handler method, the thread is still concentrating on the loop, and won't give attention to the new form I'm trying to make in the handler! Strange thing is, if I just use something small, like a MessageBox, it doesn't cause an issue, just trying to instantiate a form causes the buttons to NOT draw. Then shortly after the program stops responding. In case you're wondering where the form code is, it's just a standard form made by .NET, that works everywhere else in the code except for in the event handler.

Thanks!

class MainClass
{
    public static void Main()
    {
        TaskIcon taskbarIcon;
        EventWatch myWatcher;

        taskbarIcon = new TaskIcon();
        taskbarIcon.Show();

        myWatcher = new EventWatch();
        myWatcher.Start();

        Application.Run();
    }
}

public class TaskIcon
{
    public void Show()
    {
        NotifyIcon notifyIcon1 = new NotifyIcon();
        ContextMenu contextMenu1 = new ContextMenu();
        MenuItem menuItem1 = new MenuItem();
        MenuItem menuItem2 = new MenuItem();

        contextMenu1.MenuItems.AddRange(new MenuItem[] { menuItem1, menuItem2 });

        menuItem1.Index = 0;
        menuItem1.Text = "Settings";
        menuItem1.Click += new EventHandler(notifyIconClickSettings);

        menuItem2.Index = 1;
        menuItem2.Text = "Exit";
        menuItem2.Click += new EventHandler(notifyIconClickExit);

        notifyIcon1.Icon = new Icon("app.ico");
        notifyIcon1.Text = "Print Andy";
        notifyIcon1.ContextMenu = contextMenu1;
        notifyIcon1.Visible = true;
    }

    private static void notifyIconClickSettings(object Sender, EventArgs e)
    {
        MessageBox.Show("Settings Here");
    }

    private static void notifyIconClickExit(object Sender, EventArgs e)
    {
        //taskbarIcon.Visible = false; // BONUS QUESTION: Why can't I hide the tray icon before exiting?

        Application.Exit();
    }
}

public class EventWatch
{
    public void Start()
    {
        string thisUser = WindowsIdentity.GetCurrent().Name.Split('\\')[1];

        WqlEventQuery query = new WqlEventQuery();

        query.EventClassName = "__InstanceCreationEvent";
        query.Condition = @"TargetInstance ISA 'Win32_PrintJob'";
        query.WithinInterval = new TimeSpan(0, 0, 0, 0, 1);

        ManagementScope scope = new ManagementScope("root\\CIMV2");
        scope.Options.EnablePrivileges = true;

        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);

        watcher.EventArrived += new EventArrivedEventHandler(showPrintingForm);

        watcher.Start();
    }
    void showPrintingForm(object sender, EventArrivedEventArgs e)
    {
        // MessageBox.Show("This will draw just fine");

        Form1 myForm;
        myForm = new Form1();
        myForm.Show(); // This causes a hangup
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风苍溪 2024-12-10 00:08:47

我的猜测是,ManagementEventWatcher 从与 UI 线程不同的线程调用 EventArrived 处理程序。然后您的 showPrintingForm 在该线程上执行,并且从与 UI 线程不同的线程访问 UI 是不好的。您需要将代码封送回 UI 线程。

My guess would be that the ManagementEventWatcher calls the EventArrived handler from a different thread than the UI thread. Then your showPrintingForm is executed on that thread and accessing UI from a different thread than the UI thread is bad. You need to marshal your code back onto the UI thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文