C#で眠っているスレッドを起こすにはどうすればよいですか?
-
14-10-2019 - |
質問
人々がそれを提案する前に: 私はスレッドを使用していません なんでも それを回避する方法を見つけようとしていることを除きます。私は.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ステータスをチェックしようとしました。スレッドがクラッシュするか、例外をスローします(申し訳ありませんが、どちらが不明です。Windowsはデバッガーが実行されていない場合はクラッシュしたことを教えてくれます。 。 .resume()は、どうやら眠っている糸に何もしないようです。
は 睡眠が期限切れになるのを待つことなく、糸を起こす方法はありますか?停止は「即時」ではないので、console.writelineが関係なく呼び出される可能性があることを理解しています。私を悩ませているのは2秒の待機です。 10日間待っている場合はどうなりますか?入ってくるスレッドを制御できないので、知る方法はありません。 防止 そんなこと...
解決
いいえ、睡眠から糸を起こす方法はありません。中断または割り込みを呼び出すことによってのみスレッドを中止することができます(どちらもthreadeBortexceptionを投げます)。
しかし、なぜ実行するときにあなたに質問するために:
new Thread(() => { Thread.Sleep(2000); Console.WriteLine("second"); })
10msのタイムアウトがまだ印刷されているため、スレッドの寿命を制御するためのコードがあなたがしたいことをしないためです。
したがって、外部threadとouterがあります。アウター(新しいスレッドを起動し、スレッド1と呼びましょう)を開始し、外部スレッドで外部呼び出しを開始します(新しいスレッドを開始し、スレッド2と呼びます)。そのため、2つの新しいスレッドを開始しました。
あなたが電話するとき outer.About()
, 、それはスレッドのみを中止します。スレッドは呼び出しによって始まります externalThread.Start()
, 、スレッド2は、何も中止していないため、完了まで実行され続けます。
余分な外側の糸であなたが何を達成しようとしているのかわかりません。これは簡単ではありません:
externalThread.Start();
externalThread.Join(lifetime);
if (externalThread.ThreadState != ThreadState.Stopped)
{
externalThread.Abort();
}
他のヒント
Waitone + Timerを使用して、未知の原点のスレッドを制御します。
または、スレッドのワーカーコードを制御できる場合:
ちょっとハッキーな方法、スレッドを起こすために使用されるタイマー/他のスレッドが好きではないときに、より「応答性の高い睡眠」を達成するために
通常の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);
}
}
両方のスレッドからアクセス可能なクラスフィールドであることに注意してください。
もちろん、これはイベント/タイマーベースの待機よりもcpu-usageの特性が悪い