我有这段代码:
Thread t = new Thread(() => UpdateImage(origin));
t.Name = "UpdateImageThread";
t.Start();
此代码在自定义控件上创建。我希望在对象即将被处置时停止这个线程(如果它正在运行)。
此自定义控件具有以下方法:
void IDisposable.Dispose()
{
/* My own code */
base.Dispose(true);
}
我认为这是放置代码的地方,但是:
我怎么知道线程正在运行? 我怎样才能对线程进行引用并停止它?
顺便说一句,UpdateImage调用了一个Web服务,所以我认为它正在等待它的所有生命。 我怎么能完成这个等待?
谢谢!
答案 0 :(得分:1)
这很大程度上取决于UpdateImage()
做了什么,以及它在处理图像时仍处于活动状态的情况下如何应对。如果UpdateImage()
是您的代码并且包含循环,您可以告诉它停止(使用像_stopping这样的字段)。如果没有,最好的办法可能是什么都不做 - 在极少数情况下,在图像仍然更新的情况下处理控件时,您需要将其留在GC中。
关于如何获取线程:通过在创建它的时间和地点保存引用,例如int私有成员_updateThread。
现在实际上停止(中止)线程是一个(非常)坏主意。
所以你需要一个指标,比如
private bool _stopping = false;
由UpdateImage()
方法决定对_stopping == true
做出反应并停止正在做的事情。
然后您的Dispose()可以使用
_stopping = true;
_updateThread.Join()
答案 1 :(得分:1)
保存线程变量't',以便以后可以重复使用。
在您的Dispose方法中,您需要以下内容:
void IDisposable.Dispose()
{
if(t.IsRunning)
{
cancelThreads = true; // Set some cancel signal that the thread should check to determine the end
t.Join(500); // wait for the thread to tidy itself up
t.Abort(); // abort the thread if its not finished
}
base.Dispose(true);
}
您应该小心中止线程,确保将关键部分代码放置在不允许线程在完成之前停止的区域中,并捕获ThreadAbortExceptions以便在中止时整理任何内容。
您可以在threads start方法
中执行类似的操作public void DoWork()
{
try
{
while(!cancelThreads)
{
// Do general work
Thread.BeginCriticalRegion();
// Do Important Work
Thread.EndCriticalRegion();
}
}
catch(ThreadAbortException)
{
// Tidy any nastiness that occured killing thread early
}
}
答案 2 :(得分:0)
我建议在自定义控件中覆盖Dispose方法。 你有你的线程的参考,你可以调用.Join()例如......