Приложение.Выход должен быть вызван дважды


У меня есть основной метод, который создает цикл сообщений под названием SysTrayApp:

void Main()
{
    Application.Run(new SysTrayApp());
}  

Мой класс SysTrayApp добавляет ContextMenu к значку в системном трее, а затем запускает другой цикл сообщений под названием MouseHook. MouseHook-это класс, который вызывает события мыши. (По образцу этого класса.)

class SysTrayApp : Form
{           
    public SysTrayApp()
    {
        // Does some GUI work    
        // Then starts another message loop
        Application.Run(new MouseHook());
    }
}

_

class MouseHook : Form
{           
    public MouseHook()
    {
        // Does some hooking stuff      
    }
}

В SysTrayApp, Application.Exit() вызывается, когда пользователь выбирает опцию выхода из контекстного меню. Проблема в том, что мне нужно дважды вызвать Exit (или добавить еще один Application.Exit) для завершения приложения. Это ожидаемо, но ... Я чувствую, что иду по неверному пути. Вызов Application.Exit() дважды кажется мне неправильным, но я новичок в мире C#. Должны ли SysTrayApp и MouseHook быть объединены в один большой класс? MouseHook не похоже, что он должен быть отдельно от окон.Форма тоже. Может быть, MouseHook должен быть на новом потоке? Есть предложения?

EDIT: Упс. MouseHook не было третьего Application.Run()

Решение

Кажется, я перестарался с мыслями. этот. Все еще изучаю C#, как я уже сказал. Но вот что работает:

Application.Run(new SysTrayApp()); в Main() есть все, что вам нужно. Чтобы начать MouseHook, просто сделайте MouseHook hook = new MouseHook(); в SysTrayApp.

Спасибо @JonSkeet за то, что помог мне понять это. Ты-машина!

1 2

1 ответ:

Ты звонишь.Application.Run в конструкторе MouseHook , а затем, когда это возвращается, вы снова вызываете Application.Run (в конструкторе SysTrayApp) - вы затем вызываете его в третий раз, когда конструктор SysTrayApp завершается. Если вы собираетесь запустить три разных цикла сообщений, вы должны ожидать, что вам придется выйти три раза (я удивлен, что вам нужно только дважды позвонить Application.Exit).

Вы не должны вызывать Application.Run в любом из ваших конструкторов-идея a блокировка конструктора до тех пор, пока насос сообщений не закончит работу, это неприятно, ИМО. Если вы действительно хотите иметь несколько циклов сообщений, они должны быть в разных потоках - но я бы не советовал вам этого делать. Вы должны быть в порядке Просто вызывая Application.Run в вашем Main методе.