0

今日、Windows フォーム アプリケーションにマルチ スレッドを追加しました。私のUIスレッドでは、 new Thread() {...}).Start(); を介してスレッドを開始しています。それ自体が ThreadPool.QueueUserWorkItem() を使用するメソッドを呼び出します。メソッドが呼び出された後、特定のアイテムが返されてスレッドが終了するまで、スレッドはキューで待機します。

new Thread(o =>
        {
            s.SimulateChanges();

            Boolean run = true;

            while (run)
            {
                SimulationResult sr = queue.WaitDequeue();

                //EOF is a static property which will be returned 
                //if the queue is at its end so I can break the while loop
                if (SimulationResult.EOF.Equals(sr))
                {
                    run = false;
                    continue;
                }

                this.simulationProgressBar.BeginInvoke((Action)delegate()
                {
                    if (sr.IsDummy && this.simulationProgressBar.Value < this.simulationProgressBar.Maximum)
                    {
                        /*...*/
                    }
                    else
                    {
                        this.resultListView.AddObject(sr);
                    }
                });
            }

            this.simulationProgressBar.BeginInvoke((Action)delegate()
            {
                this.ToggleSimulationControls(true);
            });
        }).Start();

そして、それは呼び出されたメソッドのコードです:

public void SimulateChanges()
{
    ThreadPool.QueueUserWorkItem(o =>
        {
            foreach (IColElem elem in collection.AsEnumerable())
            {

                /*lot of code*/

                queue.Enqueue(new SimulationResult() { IsDummy = true });

            }
            log.Debug("Finished!");

            queue.Enqueue(SimulationResult.EOF);

        });
}

My Queue は、オブジェクトがエンキューされるまでスレッドがデキューを待機できるようにする自己記述クラスです。

VS2010 がファイル ハンドルを削除しないため、デバッグを停止した場合 (停止デバッグを使用するか、単にアプリケーションを閉じる) を除いて、すべて正常に動作しています。スレッドが正しく終了しないことに関係があると思います。これを保証できる方法はありますか?

アドバイスをありがとう:-)

4

1 に答える 1

1

質問のすべての側面を説明するのは難しい。しかし、プログラマーが最初にスレッドを使い始めたときによくある間違いを犯しています。ユーザーがメイン ウィンドウを閉じたときにスレッドの実行が停止することを確認していません。やりがちな間違いです。UI スレッドが多くの単調な作業を処理します。ユーザーがアプリのメイン ウィンドウを閉じたときに自動的に終了することも含まれます。したがって、問題の少なくとも一部は、メイン ウィンドウを閉じることができたことです。しかし、実際にはプロセスを終了しませんでした。ビルドが機能しません。プログラムの EXE はまだ使用中です。

スレッドが何をしているかに関係なく、ユーザーがウィンドウを閉じることを考えると、スレッドを適切にシャットダウンすることは非常に難しい場合があります。オペレーティング システム コールの奥深くに埋もれて、完了するのを待っている緊張病の可能性があります。コードを実行していないときに終了するように要求するのは難しいです。

非常に単純な解決策があります。少なくとも、プロジェクトを続行するか、抱えている問題の半分を解決するのに十分です。スレッドを「プログラム終了時に自動的に強制終了」としてマークすると、CLR が処理します。次のように IsBackground プロパティを使用します。

var t = new Thread(o =>
        {
           // Lotsa code
        });
t.IsBackground = true;
t.Start();

しかし、その種の殺害について優雅なことは何もないことを覚えておいてください. ファイルを書き込んでいるか、サーバーと通信している場合、ファイルが部分的に書き込まれたり、サーバーが非常に混乱したりする可能性があります。それ以外の場合は、タスク マネージャーでプログラムを強制終了するのと同じです。

于 2013-04-15T17:16:55.347 に答える