1

シンプルで非常に文字通りのWPFがあり、[開始]をクリックすると作業が開始され、[停止]をクリックすると停止します。ワーカー/バックグラウンドスレッドを開始するためのコードは次のとおりです。

--- variables ---
Thread[] thd;
bflag = false;

--- Start background worker when Start button is clicked ---
private void btnStart_Click(object sender, RoutedEventArgs e)
{
   Thread startFileCopy = new Thread(() => startFC());
   startFileCopy.Start();  
}

--- StartFC code ---
private void startFC()
{
   bflag = true;
   thd = new Thread[3];
   for(int i=0; i<3; i++)
   {
      thd[i] = new Thread(copynow);
      thd[i].Start();
   }
}

--- copynow code ---
private void copynow()
{
   while(bflag)
   {
      if (filecount == 0)
        bflag = false;
      else
      {
         // --- copy file ---
         Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
               new Action(() => copyFile(<filename to be copied>)));
         // --- update progressbar ---
         Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
               new Action(() => updateProgressbar(++1)));
      }
   }
}

これを止めるために、キャンセルボタンで、送信を優先して別のスレッドをディスパッチし、bflagをfalseに設定しました。ただし、UIの応答に基づいて、プログレスバーはまだ更新中であり、ファイルのコピーは続行されます。停止ボタンのコード:

--- Stop when stop button is clicked ---
private void btnStop_Click(object sender, RoutedEventArgs e)
{
   Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Send, 
              new Action(() => stopThreads()));
}

--- stopThreads code ---
private void stopThreads()
{
   bflag = false;
   if (thd != null)
     for (int i = 0; i < THREAD_COUNT; i++)
       if (thd[i].IsAlive)
          thd[i].Join(3000);
}

私は何が間違っているのですか?前もって感謝します!

4

1 に答える 1

2

copyFileスレッドメソッドの問題は、次の方法でメソッドの非同期実行を繰り返し開始することBeginInvokeです。

// --- copy file ---
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
    new Action(() => copyFile(<filename to be copied>)));

これにより、Dispatcherキューで実行するためにキューに入れられる多くの操作が作成されます。スレッドが停止している場合でも、これらのキューに入れられた操作がまだたくさん残っているため、スレッドはまだ実行されていると思われます。

スレッドメソッドで実際にコピー操作を実行するようにコードを変更する必要があります。

private void copynow()
{
    while (bflag && filecount > 0)
    {
        copyFile(<filename to be copied>);

        // update progressbar by synchronous Invoke instead of BeginInvoke
        Application.Current.Dispatcher.Invoke(
            new Action(() => updateProgressbar(++1)));
    }
}
于 2013-03-03T18:07:45.047 に答える