我有一个独立的应用程序,可以创建许多线程,用于与我们的某个服务器执行各种事务。其中一个线程在给定的时间间隔内轮询服务器。我已经让Thread.Sleep(user_supplied_time_interval)
使轮询线程在下一次轮询尝试之前等待给定的时间间隔。现在在关闭应用程序期间,我想要Abort()
所有线程。为此,我将继续引用parentThread
中的轮询线程并在pollerThread.Abort(); pollerThread.Join();
中调用parentThread
。但是我已经知道我无法中止睡眠线程。所以我在System.Threading.ThreadAbortException
上获得了Thread.Sleep(user_supplied_time_interval)
。
我显然可以设置一些布尔值来反映轮询器是要停止的,并在线程退出休眠状态后检查该布尔值。但是,如果轮询间隔很长,这也会延长应用程序退出,因为轮询器只有在退出休眠状态后才会返回。
这个问题的标准解决方案/方法是什么?或者我应该单独抓住System.Threading.ThreadAbortException
并忽略它。
答案 0 :(得分:2)
你应该不惜一切代价避免使用Thread.Abort,它可能导致各种奇怪的事情发生。
您可以使用ManualRestEvent代替,等待超时的事件与Sleep非常相似,您可以随时使用ManualRestEvent.Set唤醒。
你甚至可以为所有线程使用相同的事件,它也可以作为你的退出标志。
答案 1 :(得分:1)
计时器示例: 定时器每2秒运行一次
Timer t = new Timer(TimerCallback, null, 0, 2000);
private void TimerCallback(Object o)
{
//Run some code here
}
答案 2 :(得分:0)
Thread.Abort不是一个好主意。
将您的主题设置为background:
pollerThread.IsBackground = true;
后台线程与前台线程相同,除此之外 后台线程不会阻止进程终止。
答案 3 :(得分:0)
在管理线程的类中添加此属性。
/// <summary>
/// Used to tell the thread to exit.
/// </summary>
private readonly AutoResetEvent _eventDelay;
/// <summary>
/// True if the worker thread is running.
/// </summary>
private bool _isRunning;
在构造函数中初始化这样的事件。
_eventDelay = new AutoResetEvent(false);
当你的工作线程需要休眠时,你可以暂停它的执行。
_isRunning = true;
while(_isRunning)
{
// do thread work stuff
if(!_isRunning)
{
continue;
}
TimeSpan delay = // calculate how long the thread should sleep
_eventDelay.WaitOne(delay);
}
现在,您可以为您的工人类设置ShutDown
方法。注意,在完成一次迭代工作之前,它不会停止线程。
/// <summary>
/// Flags the job to shutdown. It will stop execution
/// as soon as possible.
/// </summary>
public void ShutDown()
{
if (!_isRunning)
{
return;
}
_isRunning = false;
_eventDelay.Set();
}
答案 4 :(得分:0)
我强烈建议您使用Reactive Extensions Framework(Rx)进行此类设置。根据间隔创建一个observable。当您不再需要轮询时,您可以处置订阅,框架将为您清理。
看一下这个例子,它可以帮助你:http://rxwiki.wikidot.com/101samples#toc28