4

人々がそれを提案する前に: 私はそれを回避する方法を見つけようとする以外の目的でThread.sleepを使用していません。.Sleep()フリーではないかもしれない他の人の将来のコードを処理しようとしています。私は物事を同期させることがどれほど恐ろしいかをよく理解しています。

コードのチャンクでスレッドを受け入れます。このスレッドの存続期間に制限を設定できるようにしたいと思います。私の通常の方法は次のようになります。

Thread outer = new Thread(() =>
{
    externalThread.Start();
    externalThread.Join();
});
outer.Start();
outer.Join(lifetime);
if (outer.ThreadState != ThreadState.Stopped)
{
    outer.Abort();
}
inner.Join();

それ以来、私は睡眠が終わる前に眠っている糸を起こせないようだということを発見しました。さらに悪いことに、10ミリ秒のライフタイムを与えた場合でも、これはコンソールに書き込みます。

new Thread(() => { Thread.Sleep(2000); Console.WriteLine("second"); })

.Abort()はスレッド実行の厳しい制限ではないことに気づきましたが。警告は2秒で十分なようですが、そうではないと思います...

WaitSleepJoinステータスと.Interrupt();をチェックしてみました。スレッドをクラッシュさせるか、例外をスローします(申し訳ありませんが、どちらかわかりません。デバッガーが実行されていない場合はクラッシュし、実行されている場合は割り込みが呼び出されなかったかのように実行されます)、2秒後もコンソールに書き込みます。.Resume()は、スリープ状態のスレッドに対しては何も行わないようです。

スリープが期限切れになるのを待たずにスレッドをウェイクアップする方法はありますか停止は「即時」ではないことを理解しています。そのため、Console.WriteLineは関係なく呼び出される可能性があります。私を悩ませているのは2秒の待機です。10日間待つとどうなりますか?入ってくるスレッドを制御できないので、知る方法がなく、そのようなことを防ぐ方法がないようです...

4

2 に答える 2

2

いいえ、スレッドをスリープから復帰させる方法はありません。スレッドを中止できるのは、AbortまたはInterruptを呼び出すことだけです(どちらもThreadAbortExceptionをスローします)。

しかし、実行するときになぜかという質問に対処するには、次のようにします。

new Thread(() => { Thread.Sleep(2000); Console.WriteLine("second"); })

10msのタイムアウトでも出力されますが、これは、スレッドの寿命を制御するためのコードが、実行したいことを実行しないためです。

つまり、externalThreadとouterがあります。外部スレッドを開始し(新しいスレッドを開始し、スレッド1と呼びます)、外部スレッドから外部スレッドを開始します(新しいスレッドを開始し、スレッド2と呼びます)。これで、2つの新しいスレッドが開始されました。

を呼び出すとouter.About()、スレッド1のみが中止されます。externalThread.Start()スレッド2を呼び出すことによって開始されたスレッドは、中止するものがないため、完了まで実行を続けます。

あなたが余分な外糸で何を達成しようとしているのかわかりません。これはもっと簡単ではないでしょうか:

externalThread.Start();
externalThread.Join(lifetime);
if (externalThread.ThreadState != ThreadState.Stopped)
{
    externalThread.Abort();
}
于 2010-12-31T05:04:31.483 に答える
0

WaitOne +タイマーを使用して、原因不明のスレッドを制御します。

または、スレッドのワーカーコードを制御できる場合:

ちょっとハッキーな方法で、スレッドをウェイクアップするために使用されるタイマー/他のスレッドが気に入らないときに、より「応答性の高いスリープ」を実現します

通常のThread.Sleepの代わりに使用してください

    private void WaitFor(int milis)
    {
        const int interval = 500;

        if (milis <= interval)
        {
            throw new ArgumentException();
        }

        var sections = milis / interval;
        for (var s = 0; s < sections && (!ShouldQuit); ++s)
        {
            Thread.Sleep(interval);
        }
    }

両方のスレッドからアクセス可能なクラスフィールドであるShouldQuitフラグに注意してください

もちろん、これはイベント/タイマーベースの待機よりも悪いCPU使用特性を持っています

于 2011-12-08T09:48:04.180 に答える