现实生活中,我们往往会遇到,要执行一个线程的方法,假如这个方法特别耗时,我怎么才能在指定的线程超时时间内,取消执行,并把线程销毁!以下是本人总结的常见几种方式!特此做下笔记!
1.使用CancellationTokenSource之基于Task实现方式
CancellationTokenSource source = new CancellationTokenSource();
source.CancelAfter(TimeSpan.FromMilliseconds(2000));
Task task=Task.Factory.StartNew(() =>
{
while (true)
{
try
{
source.Token.ThrowIfCancellationRequested();
Console.WriteLine("子方法执行中...");
Thread.Sleep(1000);
Console.WriteLine("子方法执行完毕...");
}
catch (OperationCanceledException ex)
{
Console.WriteLine("已捕获取消异常:" + ex.Message);
break;
}
catch (Exception ex)
{
Console.WriteLine("异常:" + ex.Message);
break;
}
}
Console.WriteLine("线程已终止");
}, source.Token);
2.使用CancellationTokenSource之基于Thread实现方式
CancellationTokenSource source = new CancellationTokenSource();
Thread thread = new Thread(new ThreadStart(() =>
{
while (true)
{
Console.WriteLine("现在时间:"+DateTime.Now);
}
}));
thread.IsBackground = true;
thread.Start();
source.Token.Register(() =>
{
Console.WriteLine("超时时间已到,开始终止线程");
thread.Abort();
Console.WriteLine("超时时间已到,终止线程完成");
});
source.CancelAfter(2000);
3.基于Thread.Join()实现
Thread thread =new Thread(new ThreadStart(() =>
{
while (true)
{
Console.WriteLine("现在时间:"+DateTime.Now);
}
}));
thread.Start();
thread.Join(2000);
Console.WriteLine("join超时时间已到,开始终止线程");
thread.Abort();
Console.WriteLine("join超时时间已到,终止线程完成");
4.基于System.Timers.Timer的实现方式
DateTime dtNow = DateTime.Now;
Thread thread = new Thread(new ThreadStart(() =>
{
while (true)
{
Console.WriteLine("现在时间:" + DateTime.Now);
}
}));
thread.IsBackground = true;
thread.Start();
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (sender,e) =>
{
double db=DateTime.Now.Subtract(dtNow).TotalSeconds;
if (db > 2)//大于2秒说明已经超时
{
Console.WriteLine("任务已执行超过了:" + db + "秒");
Console.WriteLine("超时时间已到,开始终止线程");
thread.Abort();
Console.WriteLine("超时时间已到,终止线程完成");
timer.Stop();
}
};
timer.Start();
5.基于信号量和CancellationTokenSource的实现方式
AutoResetEvent autoReset = new AutoResetEvent(false);
CancellationTokenSource source = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{
while (true)
{
source.Token.ThrowIfCancellationRequested();
Console.WriteLine("子线程:Work starting.");
// Simulate time spent working.
Thread.Sleep(5000);//new Random().Next(500, 2000)
autoReset.Set();
// Signal that work is finished.
Console.WriteLine("子线程:Work ending.");
}
}
catch (Exception e)
{
autoReset.Set();
Console.WriteLine("子线程收到异常:"+e.Message+",线程退出!");
// throw;
}
}, source.Token);
Console.WriteLine("主线程只等待1秒");
autoReset.WaitOne(1000);//等待超过1秒,则需要取消该线程
Console.WriteLine("主线程等待超时,开始继续执行,同时调用Source.Cancel()");
source.Cancel();