-1

新しいスレッドでいくつかの作業を行い、結果を静的リストに保存するために必要なアプリケーションを作成しています。その後、スレッドは自然に終了します。一度に実行できるこの追加スレッドのインスタンスは1つだけであるため、スレッドの作成を担当する関数がすでに機能しているスレッドを見つけると、それが戻るはずです。

アプリケーションを作成するとき、私はmsdnでこのガイドを使用していました:http://msdn.microsoft.com/en-us/library/7a2f3ay4%28v=vs.80%29.aspx

このガイドによると:

// Create the thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);

// Start the worker thread.
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread...");

// Loop until worker thread activates.
while (!workerThread.IsAlive);

// Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(1);

だから私は私のアプリでこのコードを使用しました:

if (TibiaControl.PathFinder.PathFinderThread != null && TibiaControl.PathFinder.PathFinderThread.IsAlive)
    return false;

TibiaControl.PathFinder Finder = new TibiaControl.PathFinder(targetX, targetY);
TibiaControl.PathFinder.PathFinderThread = new Thread(new ThreadStart(Finder.FindPath));
TibiaControl.PathFinder.PathFinderThread.Start();
SystemControl.DebugMessage(0, "_findPath -- 1");
while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;
Thread.Sleep(1);
SystemControl.DebugMessage(0, "_findPath -- 2");

しかし、この関数を高頻度で実行すると(20〜30ミリ秒に1回など)、アプリがスタックすることがあります

while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;

行とメインスレッドが無限ループでスタックします(whileループが発生する前にスレッドがすでに作業を完了しているように)。どうすれば修正できますか?

4

3 に答える 3

2

例から不要なコードをやみくもにコピーした可能性があると思います。

while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;
Thread.Sleep(1);

これを行った理由は、RequestStop メソッドの有用性を実証するためでした。

于 2013-02-19T16:03:38.587 に答える
1

そのコードを有用なアプリケーションのソースとして使用するつもりはありません。まず第一に、スレッドを待機させるためのはるかに優れた方法があります。たとえば、ManualResetEventSlim. 第二に、あなたが投稿したコードからは かどうかを判断するのは困難IsAliveですvolatile。それでも、特別なコードに関して何もしないx86システムでも。より安全で明示的な形式のスレッドセーフな値の読み取りを使用することをお勧めします。例えば:

while (0 == Interlocked.Read(ref workerThread.IsAlive)); 

これは、新しい変数 IsAlive の作成をlong に変更することを意味します。しかし、シングル CPU システムでは、唯一の CPU をビジーにし、他のスレッドがそれを使用する可能性はほとんどありません。他のスレッドに制御を渡す必要があります。

while (0 == Interlocked.Read(ref workerThread.IsAlive)) Thread.Sleep(1);

しかし、そのサンプルコードから始めるのは悪い考えだと思います。あなたがする必要があることを理解し、それを詳細にしてみてください...

詳細については、http://msdn.microsoft.com/en-us/magazine/jj863136.aspxおよびhttp://msdn.microsoft.com/en-us/magazine/jj883956.aspxを参照してください。

于 2013-02-19T16:01:57.660 に答える