0

Windows フォーム C# アプリケーションのマルチスレッド アプリで問題が発生しています。このアプリケーションはマルチコア マシンでは正常に動作しますが、シングル コア マシンで実行するとすべてのスレッドがハングします。私が使用しているbackgroundWorker、コードは次のとおりです。

 class custonTime // delay class
 {
     public void sleep_sec(int sleep)
     {
         int time_now = Environment.TickCount;
         int time_sleep = sleep;
         while ((Environment.TickCount - time_now) < time_sleep) ;
     }
 }

UI のボタンを押すと、フラグactiondoAlways設定されtrue、次のバックグラウンドワーカーが開始されます。backgorundworker1 は待機し、適切なタイミングでタスクを開始します。もう 1 つはタスクを実行します。

 private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
 {
     while(action)
     {
         if(doItAlways)
         {
             //do important tasks
         }
         if(task1)
         { 
             //do things
             task1 = false;
         }
         if(task2)
         { 
             //do things
             task1 = false;
         }
    }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    task1=true;
    manegerTimewr2.sleep_sec(12000);//call delay class to wait 12 secs
    task2=true;
    manegerTimewr2.sleep_sec(12000);//call delay class to wait 12 secs
}

私の遅延クラスは私だけでbackgorundworker1なくbackgroundworker2、 flag によって起動されたタスクを実行することを不可能にしますdoItAlways。アプリケーションは while ループが終了したときにのみ解放されます。

そして、それはシングルコアマシンでのみ発生します。

別の方法はありますか?他のスレッドをブロックすることなく、しばらく時間が経過するまでスレッドをハングアップする直接的で簡単な方法は?

Thread.Sleep経過時間はマシンによって大きく異なるため、メモは機能しません。

4

3 に答える 3

0

Thread.Sleep というメソッドを使用して、指定された時間の待機を実装します。

于 2013-08-31T15:42:45.610 に答える
0

問題は、BackgroundWorker通常、マシン上の CPU/コアと同じ数のスレッドを含むスレッド プールを内部的に使用することです。sleep_secしたがって、シングル CPU マシンでは、BackgroundWorkers を処理するスレッドは 1 つしかありません。最初のスレッドが両方の呼び出しを実行し、その後で 2 つ目のスレッドが開始されるように、それらは順番にスケジュールされていると思います。

一方、マルチコア マシンでは、スレッド プールにより多くのスレッドがあるため、期待どおりに動作します。

これはUIの操作を必要としないため、「待機」には「通常」Thread( と一緒にThread.Sleep、ループを使用しないでください)を使用できます。whileオブジェクトを使用することもできTimerます。これは、まさにこの目的 (指定された時間の後にイベントを発生させる) を目的としています。

于 2013-08-31T16:11:22.037 に答える
0

を使用するBackgroundWorker代わりに、新しい を起動し、そのスレッドThreadの を手動で設定します。ThreadPriorityその後、使用できるようになり、スレッドの優先度が高くなるため、より正確に機能Thread.Sleepするはずです。最終的に何をすべきかについては次のとおりです。

void Run()
{
    // some initialization stuff
    new Thread(DoWork1) { Priority = ThreadPriority.AboveNormal }.Start();
    new Thread(DoWork2) { Priority = ThreadPriority.Highest }.Start();
}

private void DoWork2()
{
    while (action)
    {
        if (doItAlways)
        {
            //do important tasks
        }
        if (task1)
        {
            //do things
            task1 = false;
        }
        if (task2)
        {
            //do things
            task1 = false;
        }
        Thread.Sleep(1);
    }
}

private void DoWork1()
{
    task1 = true;
    Thread.Sleep(12000);//call delay class to wait 12 secs
    task2 = true;
    Thread.Sleep(12000);//call delay class to wait 12 secs
}
于 2013-08-31T16:13:53.223 に答える