次のスニペットについて考えてみます。
if(form1.isLoggedIn)
{
//Create a wait handle for the UI thread.
//the "false" specifies that it is non-signalled
//therefore a blocking on the waitone method.
AutoResetEvent hold = new AutoResetEvent(false);
filename = Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username);
Flow palm = new Flow(new FlowArguments(form1.username, filename), hold);
System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon();
System.Windows.Forms.ContextMenuStrip notificationIconContext = new System.Windows.Forms.ContextMenuStrip();
//Create a context menu strip
ToolStripMenuItem contextAbout = new ToolStripMenuItem("About");
ToolStripMenuItem contextExit = new ToolStripMenuItem("Exit");
//properties of notifyicon that SO dosnt care for including a event handler for the mouse click events.
//wait for the background thread to finish.
hold.WaitOne(Timeout.Infinite);
MessageBox.Show("Thankyou, exiting...");
form1.Dispose();
}
ご覧のとおり、FLOWクラスは非常に単純です。実行されるThreading.Timerがあります。したがって、UIスレッドでは、WaitHandle.WaitOne()メソッドを呼び出す必要があります。そうしないと、UIスレッドが終了し、アプリケーションが終了します。
私の目標:GUIがないので、通知アイコンを作成したいと思います。クリックできず、応答しないことを除いて、すべてが機能します。これは、UIスレッドで作成されているためです。FlowクラスもUIスレッドにあるため(Flowクラスのタイマーはバックグラウンドスレッドにあります)、フロークラスに入れることができません。
では、Flowクラスでタイマーを実行しているときにnotifyiconの応答性を維持するにはどうすればよいですか?ウェイトハンドルが私の解決策だと思いましたが、ブロッキングメソッドなので機能しません。
他のアイデア/解決策はありますか?
編集:Richの回答への応答:Flowクラスはバックグラウンドスレッド上にあり、すべてが正常に実行されます。しかし、UIスレッドにウェイトハンドルを追加しないと、main()はUIスレッドで終了するため、プログラム全体が終了します。(タイマーがバックグラウンドスレッドで有効になっている場合でも)。ウェイトハンドルの別の解決策はありますか?Flowクラスがそのことを行うためにそれを残さなければならないからです。取り出すとプログラムが終了し、そのままにしておくとUIスレッドがブロックされるため、notifyiconが機能しません。