2013-10-11 58 views
1

我正在使用BackgroundWorker来处理长时间运行的外部操作。但是用户可以选择取消后台操作。由于我的自定义BackgroundWorker支持Thread.Abort(),因此当用户从主线程触发Cancel时,我所做的全部为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

Abort方法依赖于工作线程与它合作。最终它会导致CLR抛出一个异常,指示线程将中止,线程可以随意处理。

当你的工作线程在执行DLL东西时,CLR是不是在控制,因此它并没有引发异常的选项。

你必须使用Win32 API TerminateThread,但这样做的选择是严重的,可能会或可能不会导致你的过程中的腐败。 TerminateThread并不是您应该选择的选项。

既然你不能修改您所呼叫的图书馆,你有两种选择。第一种也是最简单的方法,降低后台线程的优先级并忽略取消后继续运行的事实。

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

TasksCancellationTokens最终不会在这种情况下帮助你,因为你最终会在同一个地方:执行库代码,将不会与你合作以取消。

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

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