终止线程的最佳方式
本文关键字:方式 最佳 线程 终止 | 更新日期: 2023-09-27 18:15:24
我正在做一个同时下载多个文件的下载器。每次下载都有自己的Form,它在线程中运行下载代码。我正在寻找终止正在运行的下载线程的最佳方法,原因有两个
- 用户取消下载
- 主要形式为封闭
目前有三种方法
- 使用
bool terminate
这样的检查变量 - 使用
Thread.Abort()
- 运行
AppDomain
线程,卸载AppDomain
线程终止
第一种方法的问题是线程一直运行直到它到达if
语句。即使关闭MainForm
,进程也会继续运行,直到所有下载线程终止。
我不太了解Thread.Abort
,但我非常不鼓励使用它。
下面是最后一种方法的代码:
public class Processor : MarshalByRefObject
{
private AsyncOperation _operation;
private AppDomain Domain { get; set; }
public delegate void ProgressChangedEventHnadler(Processor sender, int progress);
public delegate void ProcessedEventHandler(Processor sender, EventArgs e);
public delegate void ExceptionOccuredEventHandler(Processor sender, Exception ex);
public event ProgressChangedEventHnadler ProgressChanged;
public event ProcessedEventHandler Processed;
public event ExceptionOccuredEventHandler ExceptionOccured;
private void OnProgressChanged(int progress)
{
if(ProgressChanged!=null)
ProgressChanged.Invoke(this,progress);
}
private void OnProcessed(EventArgs e)
{
if (Processed != null)
Processed.Invoke(this, e);
}
private void OnExceptionOccured(Exception ex)
{
if (ExceptionOccured != null)
ExceptionOccured.Invoke(this,ex);
}
public Processor()
{
_operation = AsyncOperationManager.CreateOperation(null);
}
public static Processor CreateInstance()
{
var locaion = Assembly.GetEntryAssembly().Location;
var domain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
var instance =(Processor)domain.CreateInstanceFromAndUnwrap(locaion, typeof (Processor).FullName);
instance.Domain = domain;
return instance;
}
public void Start()
{
var mainThread = new Thread(Process);
mainThread.Start();
}
public void Stop()
{
AppDomain.Unload(Domain);
}
private void Process()
{
//Do the Work and raise events like
//_operation.Post(e => OnProcessed((EventArgs)e), EventArgs.Empty);
}
}
一般有两种选择:
-
允许线程终止自己。这包括你的第一个选择。
-
从外部终止线程。
就是这样。一般来说,它们都不能阻止线程在应该(从程序员的意图角度来看)终止后无限期地运行。
最可预测的方法是第一个。如果终止花费的时间太长,请尝试以较小的步骤执行处理,以便更频繁地检查终止标志。另外,请注意IsBackground
标志,这将有助于解决应用程序无法关闭自身的问题。
finally
块)都可能在执行过程中被中断,这可能导致一些不希望的结果(例如一些未被释放的非托管资源)-正如Thread.Abort
文档中所解释的那样。请注意,最新版本的。net框架中的第三种方法相当于在执行线程上调用Abort
方法,如文档中所述:
domain中的线程使用
Abort
方法终止,该方法在线程中抛出ThreadAbortException
。虽然线程应该立即终止,但它可以在finally子句中继续执行不可预测的时间。
因此,使用这两个中的Thread.Abort
似乎更好,因为它更简单,更具可读性。
如果第一种方法有问题,如果你很清楚线程正在执行的操作类型,并且在中间中断它们没有问题,那么"野蛮"方法应该是好的