Приложение в трее запускается с помощью Application.Run(new MyTrayApp()):
Код: Выделить всё
class MyTrayApp : ApplicationContext
{
private NotifyIcon trayIcon;
public MyTrayApp()
{
trayIcon = new NotifyIcon()
{
Icon = Resources.app_icon,
ContextMenu = new ContextMenu(new MenuItem[] {
new MenuItem("Exit", Exit)
}),
Visible = true
};
// context is still null here
var context = SynchronizationContext.Current;
// but I want to invoke UI thread in hardware events
MyHardWareController controller= new MyHardWareController(context);
}
void Exit(object sender, EventArgs e)
{
// context is accessible here because this is a UI event
// too late tho
var context = SynchronizationContext.Current;
trayIcon.Visible = false;
Application.Exit();
}
}
- недоступен, поскольку нет элементов управления.
Код: Выделить всё
Control.Invoke() - Поиск предполагает, что SynchronizationContext.Current следует сохранить для последующего вызова, но событие ApplicationContext.Load() отсутствует...?
- Я заметил, что MainForm имеет значение null во всем цикле. Интересно, как в этом случае инициализируется SynchronizationContext?
Просто чтобы добавить некоторую справочную информацию о том, почему я хотел бы вызвать поток пользовательского интерфейса. Это связано с тем, что System.Threading.ThreadStateException будет выброшено при попытке доступа к ресурсам Windows, таким как буфер обмена или SendKeys, в другом потоке:
Код: Выделить всё
HResult=0x80131520
Message=Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.
Source=System.Windows.Forms
StackTrace:
...
- уже установлен для основной функции (без эффекта).
Код: Выделить всё
[STAThreadAttribute] - Создание нового потока STA приведет к удалению антивирусом моего приложения при компиляции.
Изменить 2:
Добавьте суть для воспроизведения ошибки:
https://gist.github.com/jki21/eb950df7b ... f105335bbf