终止线程的最佳方式

本文关键字:方式 最佳 线程 终止 | 更新日期: 2023-09-27 18:15:24

我正在做一个同时下载多个文件的下载器。每次下载都有自己的Form,它在线程中运行下载代码。我正在寻找终止正在运行的下载线程的最佳方法,原因有两个

  • 用户取消下载
  • 主要形式为封闭

目前有三种方法

  1. 使用bool terminate
  2. 这样的检查变量
  3. 使用Thread.Abort()
  4. 运行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似乎更好,因为它更简单,更具可读性。

如果第一种方法有问题,如果你很清楚线程正在执行的操作类型,并且在中间中断它们没有问题,那么"野蛮"方法应该是好的