0

中止しようとしているスレッドがあります。私がやったことは次のとおりです。

randomImages = new Thread(new ThreadStart(this.chooseRandomImage));
            randomImages.Start();

これはスレッドによって呼び出されるメソッドです

bool threadAlive = true;
public void chooseRandomImage()
    {
        while(threadAlive)
        {
           try
            {
                //do stuff


            }

            catch (Exception exe)
            {
                MessageBox.Show(exe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }
    }

ここで、スレッドの停止ボタンをクリックすると、threadAliveをfalseに設定するだけです。問題は、ある種の勢いを集めたかのように、スレッドがすぐに停止しないことです。スレッドを即座に停止し、場合によっては再開するにはどうすればよいですか?

 private void butStopThread_Click(object sender, EventArgs e)
    {

        threadAlive = false;


        if(threadAlive == false)
        {
           //do stuff
        }


    }
4

3 に答える 3

2

申し訳ありませんが、それが最善の方法です。.NET 4.0以降を使用する場合は、スレッドではなくタスクを使用する必要があります。そうすると、変数とほぼ同じように機能するCancellationTokenと呼ばれるものがあります。

その後、キャンセル後、処理が終了するまで待ちます。それを迅速に行う必要がある場合は、キャンセルのチェックをよりきめ細かくします。つまり、より頻繁にチェックします。

http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellationで説明されているように、スレッドを中止すると重大な副作用が発生する可能性があります。これが、この方法を一般的に使用すべきでない理由です。

いいえ、停止したスレッドなどを魔法のように再開することはできません-これはロジックに入れる必要があります(再開ポイント、保存ポイント、段階的に実行されるトランザクション、終了した場所を記憶する)。

補足として-タスクを使用しないことを主張し、.NETの最新バージョンにアクセスできる場合、インターロックアクセスクラスメソッドを使用する場合は、Volatileは必要ありません。これは、定義ごとにスレッドセーフなアセンブラ命令にまで及びます。

于 2013-01-05T11:36:40.987 に答える
1

Abortを呼び出して別のスレッドからスレッドを終了することは可能ですが、これにより、影響を受けるスレッドがタスクを完了したかどうかを気にせずに強制的に終了し、リソースをクリーンアップする機会がなくなります。この例に示されている手法が推奨されます。

中止方法 を使用する必要がありますが、お勧めしません

于 2013-01-05T11:21:20.937 に答える
0

提供された情報から、threadAlive変数はワーカースレッドとUIスレッドの両方からアクセスされているようです。volatileキーワードを使用してthreadAliveを宣言してみてください。これにより、同期の問題なしにクロススレッドアクセスが確実に発生します。

volatile bool threadAlive;

スレッドを再開するには、最初に、必要なすべてのクリーンアップが実行されていることを確認する必要があります。メイン/UIスレッドのスレッドオブジェクトでJoinメソッド呼び出しを使用して、スレッドが安全に終了することを確認します。再起動するには、スレッドでStartメソッドを呼び出すだけです。

randomImages.Join();
于 2013-01-05T11:41:43.817 に答える