これは奇妙なものです。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
のコードが機能します。これは、少なくとも一言を言うのは非常に混乱しています。
あなたは完全にアプリケーションメッセージポンプを飢えています。私はどれくらい長くそれが空気なしで生き残ることができるか分かりません。 –
1500ファイルが追加されました。ブロックする前にそれらのファイルは処理されません。 –
@HenkHoltermanこれは実行に約20秒以上かかってはならず、内部ツールでしかないので、Windowsがそうでないと判断した場合は騒がしくなりません。応答する –