4

これは奇妙なものです。キューが空にThread[]なるまで各アイテムを処理するワーカースレッドがありConcurrentQueue<string>、その時点で残りのプログラムが続行されます。

これは約 1500 アイテムまで機能し、その時点ですべてのスレッドがブロックされたままWaitSleepJoinになり、キュー内のアイテムはまったく処理されません。

コードをステップ実行しようとしましたが、スレッドがまだ作成され、開始され、生きているように見えますが、すぐにブロックされ、関連する機能が実行されません。

私は完全に混乱しているので、助けていただければ幸いです!

関連するコードのセクションは次のとおりです。

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

            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++;
        }
    }
}

変換機能:

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");
}

紛らわしい部分は、これがすべてキュー内のアイテム数を中心に展開しているように見えますが、オーバーフローはないようです。

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

更新 2:UseShellExecute = falseコードが機能する場合。控えめに言っても、これは非常に混乱します。

4

1 に答える 1