我正在玩托盤應用程序。應用程序僅在系統托盤中運行,並且沒有與之關聯的Windows窗體。應用程序使用ManagementEventWatcher並在特定情況下顯示警報窗口。托盤應用程序:從後臺線程事件處理程序在主線程上創建UI
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AppContext());
}
...
public class AppContext : ApplicationContext
{
private System.ComponentModel.IContainer _components;
private NotifyIcon _notifyIcon;
private ContextMenuStrip _contextMenu;
private ManagementEventWatcher _regWatcher;
public AppContext()
{
//Initialize context menu & tray icon
_regWatcher = new ManagementEventWatcher(query);
_regWatcher.EventArrived += new EventArrivedEventHandler(_regWatcher_EventArrived);
_regWatcher.Start();
}
void _regWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
Alert.Show("Alert!", "My Message", someParam);
}
}
...
public class Alert
{
public static void Show(string title, string message, string extraInfo)
{
new Alert(title, message, extraInfo).ShowDialog();
}
private Alert(string title, string message, string extraInfo)
{
InitializeComponent();
this.Icon = Properties.Resources._default;
this.Text = title;
this.label1.Text = message;
this.linkLabel1.Text = extraInfo;
}
}
有趣的是,它不抱怨線程安全的方式不訪問UI。我想因爲它只存在於這個後臺線程上。但稍後當表單嘗試訪問剪貼板時,它不起作用,因爲它正在MTA線程上運行。到目前爲止,我發現的所有類似問題都有調用Invoke的窗體,或者可以選擇使用BackgroundWorker。在這種情況下,在主線程上創建和顯示Alert Form的最佳方法是什麼?
見安迪·懷特菲爾德的博客[這裏](http://nosuchblogger.com/post/60/applicationcontext-and-the-ui-thread),他採用的是**的SynchronizationContext()**解決類似的問題。 –
@Idle_Mind這是對的錢!我將探討這一點。 – xr280xr
我不完全確定你的意思,@HansPassant。我可能在那裏做了一個假設,但是我知道的是當_regWatcher_EventArrived事件處理程序執行時,System.Threading.Thread.CurrentThread.ThreadState是Background和System.Threading.Thread.CurrentThread.ApartmentState是MTA。 – xr280xr