我正在使用同时下载多个文件的下载程序。每个下载都有自己的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);
}
}
答案 0 :(得分:2)
一般来说,您有两种选择:
允许线程自行终止。这涵盖了您的第一个选择。
从外部终止线程。这涵盖了您的其他选择。
就是这样。一般来说,在 (从程序员的意图的角度来看)终止后,它们都不会阻止线程无限期地运行。
最可预测的方法是第一个。如果终止时间过长,请尝试以较小的步骤进行处理,以便更频繁地检查终止标志。另外,请注意IsBackground
标志,这将有助于应用程序无法自行关闭。
其他选项的整个问题是任何代码(除了一些特殊情况,如finally
块)可能会在执行过程中被中断,这可能导致一些不受欢迎的结果(例如一些未发布的非托管资源) - 正如Thread.Abort
文档中所述。
请注意,最新版本的.NET框架中的第三种方法等同于在执行线程上调用Abort
方法,如the documentation中所述:
域中的线程使用
Abort
方法终止,该方法在线程中抛出ThreadAbortException
。虽然线程应该立即终止,但它可以在finally子句中继续执行不可预测的时间。
所以从这两个中使用Thread.Abort
似乎更好,因为它更简单,更易读。
如果第一种方法有问题,并且如果你很清楚线程正在执行的操作类型,并且中断它们之间没有问题,那么“野蛮”方法应该没问题。