从计时器事件中止线程

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循环可能是一个不好的例子.

Dar*_*con 5

如评论中所述,您不应该使用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)

但是您应该找到另一种更优雅地终止线程的方法,或者重新编写代码以不需要显式线程.