У меня есть Timer
, который должен отменить Thread
, если для этого потребуется слишком много времени.
System.Timers.Timer timer_timers = new System.Timers.Timer();
Thread thread = new Thread(startJob);
thread.Name = "VICTIM_THREAD";
при запуске метода Thread
я запускаю Timer
и передаю текущий поток событию в качестве параметра.
public void startJob()
{
Debug.WriteLine("Name: " + Thread.CurrentThread.Name);
timer_timers.Elapsed += (sender, e) => T_Elapsed(sender, e, Thread.CurrentThread);
timer_timers.Interval = 5000;
// Start simulation process
while (true)
{
Thread.Sleep(700);
Debug.WriteLine("Thread: " + Thread.CurrentThread.Name + " ALIVE: " + thread.IsAlive);
}
}
Событие таймера:
private void T_Elapsed(object sender, ElapsedEventArgs e, Thread currentThread)
{
// EDIT: show the correct NAME! of the thread
Debug.WriteLine("Name: " + currentThread.Name);
System.Timers.Timer tim = sender as System.Timers.Timer;
currentThread.Abort(); // <-- this line throws exception
if (tim != null)
{
tim.Stop();
}
}
Но вызов Abort
вызывает исключение:
«Невозможно оценить выражение, потому что код оптимизирован или собственный фрейм находится на вершине стека вызовов»
и нить остается живой. Если я запускаю таймер до startJob()
и передаю поток напрямую, он работает нормально.
public void startThread()
{
timer_timers.Elapsed += (sender, e) => T_Elapsed(sender, e, thread);
timer_timers.Interval = 5000;
timer_timers.Start();
thread.Start();
}
public void startJob()
{
// Start simulation process
while (true)
{
Thread.Sleep(700);
Debug.WriteLine("Thread: " + Thread.CurrentThread.Name + " ALIVE: " + thread.IsAlive);
}
}
Вопрос: Почему не работает Thread.CurrentThread
версия? это потому, что мне также пришлось бы прервать поток таймера? Что мне здесь не хватает?
Я нашел ответы на это исключение, например this и this взяты из другого контекста и не очень помогают мне понять, почему.
РЕДАКТИРОВАТЬ: Я знаю, что это неправильный способ прервать или отменить поток. Его задача - открыть SerialPort. Но раз в ~ 200-й раз поток просто никогда не вернется, и мне нужно его убить, не говоря уже о последствиях. имитация цикла while может быть плохим примером.
Thread.Abort()
, так как он может оставить домен приложения в неопределенном состоянии. Единственное исключение из этого - если вы пытаетесь принудительно завершить работу приложения, и в этом случае вас не волнует неопределенное состояние. - person Enigmativity   schedule 07.07.2016Thread.CurrentThread
. Ответ Dark Falcon правильный. - person   schedule 07.07.2016Environment.FailFast()
. Другими словами, нет обстоятельств, при которых вы должны звонитьThread.Abort()
. - person Matthew Watson   schedule 07.07.2016Dispose
на экземпляреSerialPort
из другого потока, чтобы разблокировать его? - person spender   schedule 07.07.2016Dispose
, к сожалению, не работает, но хорошая идея. прерывание потоков тоже не помогает. Остается застрять вport.Open();
. Я нашел еще пару сообщений. Старые посты ... интересная проблема. - person Mong Zhu   schedule 08.07.2016