2

これは奇妙なものです。ConcurrentQueue<string>の項目をそれぞれ処理するワーカースレッドのThread[]があります。キューが空になるまで、残りのプログラムは続行されます。Worker Threads Blocking ConcurrentQueueの項目が多すぎる

これは、すべてのスレッドがWaitSleepJoin状態でブロックされたままで、約1500項目まで動作し、キュー内の項目を一切処理しません。

私は自分のコードをステップ実行しようとしましたが、スレッドはまだ作成されており、まだ起動していますが、すぐにブロックされ、関連する機能は実行されません。

私は完全にflummoxedので、どんな助けもありがとう!

コードの関連セクションは以下の通りです:

メインスレッドセグメント:

  ConcurrentQueue<string> convertionQueue = new ConcurrentQueue<string>(); 
      List<Thread> converterThreads = new List<Thread>(); 
      Directory.GetFiles(_folderOne, "*.fdf", SearchOption.AllDirectories).ToList().ForEach(file => convertionQueue.Enqueue(file)); 
      Directory.GetFiles(_folderTwo, "*.fdf", SearchOption.AllDirectories).ToList().ForEach(file => convertionQueue.Enqueue(file)); 
      int filesDone = 0; 
      int totalFiles = convertionQueue.Count; 
      progressBar.Maximum = totalFiles; 
      panel1.Visible = true; 
      for (int i = 0; i < Environment.ProcessorCount; i++) 
      { 
       converterThreads.Add(new Thread(() => ConvThreadWorker(convertionQueue, ref filesDone))); 
      } 
      converterThreads.ForEach(thread => thread.Start()); 
      DateTime lastTick = DateTime.Now; 
      int lastFilesDone = 0; 
      int[] valuesSpeed = { 1, 1, 1, 1, 1 }; 
      int[] valuesTime = { 1, 1, 1, 1, 1 }; 
      int counter = 0; 
      while (converterThreads.Any(thread => thread.IsAlive)) 
      { 

       TimeSpan t = DateTime.Now - lastTick; 
       int deltaFiles = filesDone - lastFilesDone; 
       double speed = (float)t.TotalMilliseconds <= 0.0 ? 0.0 : deltaFiles/(float)t.TotalMilliseconds; 
       double tMinus = speed <= 0 ? 0.0 : (totalFiles - filesDone)/speed; 
       int currentSpeed = (int)(speed * 1000); 
       int currentTime = (int)(tMinus/1000); 
       valuesSpeed[counter] = currentSpeed; 
       valuesTime[counter] = currentTime; 
       lblFilesLeft.Text = string.Format("{0}/{1}", filesDone, totalFiles); 
       lblSpeed.Text = valuesSpeed.Sum()/5 + " /s"; 
       lblTime.Text = valuesTime.Sum()/5 + " s"; 
       lblFilesLeft.Update(); 
       lblSpeed.Update(); 
       lblTime.Update(); 
       progressBar.Value = filesDone; 
       progressBar.Update(); 
       lastTick = DateTime.Now; 
       lastFilesDone = filesDone; 
       counter = ++counter % 5; 
       Thread.Sleep(500); 
      } 

ワーカー機能:

private void ConvThreadWorker(ConcurrentQueue<string> queue, ref int fileCounter) 
{ 
    while (!queue.IsEmpty) 
    { 
     string file; 
     if (queue.TryDequeue(out file)) 
     { 
      ConvToG(file); 
      fileCounter++; 
     } 
    } 
} 

Convertion機能:

private void ConvToG(string file) 
{ 
    MessageBox.Show("Entering Convertion Function"); 
    if (!_fileCreationDictionary.ContainsKey(file)) 
    { 
     DateTime lastTimeModified = File.GetLastWriteTime(file); 
     _fileCreationDictionary.AddOrUpdate(file, lastTimeModified, (key,oldvalue)=>lastTimeModified); 
    } 
    ProcessStartInfo procStart = new ProcessStartInfo 
    { 
     Arguments = file, 
     UseShellExecute = true, 
     FileName = Fdfg, 
     WindowStyle = ProcessWindowStyle.Hidden 
    }; 
    Process process = new Process {StartInfo = procStart}; 
    MessageBox.Show("Starting convertion process"); 
    process.Start(); 
    process.WaitForExit(); 
    MessageBox.Show("Finished"); 
} 

confusキュー内のアイテムの数を中心にどのように回転するのかが分かりますが、オーバーフローがないようです。

更新:mboxの表示を追加すると、コードのprocess.Start()セクションにフリーズし、エラーは発生せず、そのポイントを超えて進まないことが示されます。

更新日2:UseShellExecute = falseのコードが機能します。これは、少なくとも一言を言うのは非常に混乱しています。

+0

あなたは完全にアプリケーションメッセージポンプを飢えています。私はどれくらい長くそれが空気なしで生き残ることができるか分かりません。 –

+0

1500ファイルが追加されました。ブロックする前にそれらのファイルは処理されません。 –

+0

@HenkHoltermanこれは実行に約20秒以上かかってはならず、内部ツールでしかないので、Windowsがそうでないと判断した場合は騒がしくなりません。応答する –

答えて

1

私は、データを照合するためのプロセスを生成するスレッドと同様のことをしました。私は実際のプロセスの開始とぶら下がりの周りに問題がありました。私が働いて私のプログラムを取得するために何をしたか、このようなものだった:

using (Process process = Process.Start(startInfo)) { 
    if(process.WaitForExit(timeOutMilliseconds)) { 
     MessageBox.Show("Process exited ok"); 
     //...snip 
    } else { 
     MessageBox.Show("Process did not exit in time!"); 
     //...snip 
     process.Kill(); 
    } 
} 

もう少しあり、バックグラウンドで起こって実行中のプロセスの数を制限することについて、などが、私は不明のため、時折それを発見されました理由は、私はタスクマネージャーでいくつかのプロセスがちょうど永遠にぶら下がって表示されます。

希望しますか?

+0

これは助けになりました、ありがとうございます。なぜそれが掛かっているのか分かりません。 –

関連する問題