0

次のスニペットについて考えてみます。

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が機能しません。

4

4 に答える 4

0

Flowオブジェクトが何であるか、またはそれが何をするのかわかりませんが、なぜそれが別のスレッドで機能し、UIスレッドをブロックしないのですか?通知アイコンはUIの一部であるため、UIスレッド上にある必要があり、別のスレッドで実行するには間違った候補になると思います。対照的に、Flowオブジェクトは、別のスレッドで生成される方が理にかなっているアプリケーションのロジックを実行しているようです。

于 2009-01-12T17:52:09.080 に答える
0

ermau が述べたように、フォアグラウンド スレッドはプロセスの終了を防ぎます。

したがって、1 つの解決策は、フォアグラウンド スレッドを使用するように Flow クラスを変更することです。Threading.Timerはシステムによって提供される ThreadPool スレッドで実行されるため、別のものを使用する必要があります。

Flow クラスを変更したくない場合は、ハンドルを待機するフォアグラウンド スレッド (UI スレッド以外) を作成するという別の解決策があります。

Thread t = new Thread((ThreadStart)delegate { hold.WaitOne(); });
t.Start();

これにより、ハンドルの「保留」がワーカー スレッドによって通知されるまでブロックするスレッドが作成されますが、UI スレッドはブロックされません。

于 2009-01-28T20:38:58.277 に答える
0

バックグラウンド スレッドとしてマークされていないアライブ スレッドは、プログラムの終了を妨げます。

于 2009-01-12T18:01:43.647 に答える