Mon*_*Zhu 1 c# multithreading timer thread-abort threadabortexception
如果它需要太多时间我必须Timer取消Thread它.
System.Timers.Timer timer_timers = new System.Timers.Timer();
Thread thread = new Thread(startJob);
thread.Name = "VICTIM_THREAD";
Run Code Online (Sandbox Code Playgroud)
在启动Thread方法时,我启动Timer并将当前Thread作为参数传递给事件.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
定时器事件:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
但这个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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题:为什么Thread.CurrentThread版本不起作用?是因为我还必须中止计时器线程?我在这里错过了什么?
我发现这个例外是这样的,这是来自不同的背景,并没有真正帮助我理解为什么.
编辑:我知道这是中止或取消线程的错误方法.它应该做的工作是打开一个SerialPort.但每次约200次,线程将永远不会返回,我需要杀死它,永远不要回避后果.模拟while循环可能是一个不好的例子.
如评论中所述,您不应该使用Abort.即使你这样做,这也是你使用它的方式的问题:
计时器不会在你的线程上运行.它们在线程池线程上运行.因此Thread.CurrentThread在你的lambda中使用将是该线程池线程.
如果你想中止创建定时器的线程,你应该做的是:在lambda之外的变量中捕获线程.
Thread myThread = Thread.CurrentThread;
timer_timers.Elapsed += (sender, e) => T_Elapsed(sender, e, myThread);
Run Code Online (Sandbox Code Playgroud)
但是您应该找到另一种更优雅地终止线程的方法,或者重新编写代码以不需要显式线程.