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 回答