需要线程终止建议

时间:2013-10-11 04:20:36

标签: c# wpf multithreading

我使用BackgroundWorker来处理长时间运行的外部操作。但是,用户可以选择取消后台操作。由于我的自定义BackgroundWorker支持Thread.Abort(),所以当用户从主线程触发取消时,我所做的只是BackgroundWorker.Abort()

但该线程实际上并未终止,它仍在完成外部进程。有什么方法可以立即终止一个帖子。

我无法控制外部处理,因此无法为while (checkThreadCancelled){}等方法发送任何标记。

下面是我的伪代码。

任何帮助?

AbortableBackgroundWorker _bgWorker;

void MainThreadFunc()
{
    _bgWorker = new AbortableBackgroundWorker();
    _bgWorker.DoWork += new DoWorkEventHandler(bg_DoWork);
    _bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    ( bg_RunWorkerCompleted );
    _bgWorker.WorkerSupportsCancellation = true; 
    _bgWorker.RunWorkerAsync();
}

void bg_DoWork()
{
    //Call external dll function for processing
}

void bg_RunWorkerCompleted()
{

   //Process completed code
}

void CancelBgProcess()
{
   if(_bgWorker != null)
      _bgWorker.Abort();
}

3 个答案:

答案 0 :(得分:3)

Abort方法依赖于与之协作的工作线程。最终它会导致CLR抛出一个异常,表明该线程将被中止,线程可以随意处理它。

当你的工作线程在DLL中执行某些操作时,CLR无法控制,因此它没有选择抛出异常。

您可以选择使用Win32 TerminateThread API,但这样做很严重,可能会也可能不会导致您的流程中出现损坏。 TerminateThread实际上不是你应该选择的选项。

由于您无法修改要调用的库,因此您有两个选项。第一种也是最简单的方法,降低后台线程的优先级,并忽略它在取消后继续运行的事实。

第二种是在单独的进程而不是线程中启动后台操作。此时,如果取消操作,您可以终止整个过程。如果你走这条路,你需要选择某种形式的IPC来传达图书馆的输入和输出参数。

在这种情况下,

TasksCancellationTokens最终无法帮助您,因为您最终会在同一个地方:执行不与您合作的库代码以便取消。

答案 1 :(得分:1)

您不想使用Thread.Abort,通常认为这是不好的做法。在SO上提出的许多问题提供了一些非常好的解释。例如:Timeout Pattern - How bad is Thread.Abort really?

尝试查看TasksCancellationTokens。请参阅此MSDN文章:http://msdn.microsoft.com/en-us/library/dd997396.aspx

答案 2 :(得分:0)

试试这个:

if (_bgWorker.IsBusy)
            {
                _bgWorker.WorkerSupportsCancellation = true;
                //To cancel the Thread if Closing the Application
                //while the Background Thread Worker is Still running on Background.
                _bgWorker.CancelAsync();                   
            }

它将停止当前线程进程并取消该线程上正在进行的操作。 可能对你有所帮助