C# 管理观察者线程-如何处理引发的异常&;参加工作?

C# 管理观察者线程-如何处理引发的异常&;参加工作?,c#,multithreading,watchdog,threadabortexception,C#,Multithreading,Watchdog,Threadabortexception,我有一个来自我不拥有的API的登录进程,该API偶尔会挂起。如果它需要的时间超过,比如说,30秒,我想杀死它并重试(因为它应该只需要2-3秒) 我对终止线程的工作原理,以及终止线程后是否需要加入有点困惑。下面是我的问题,下面是我尝试做的一个例子: 问题: Abort在其调用的线程中引发线程中止异常。那会传播吗?我是否需要在调用线程中显式地处理它,还是该线程刚刚死亡 我是否需要加入一个中止的线程,这样它就不会变成僵尸,或者我只是被*NIX编程世界弄糊涂了 public static Session

我有一个来自我不拥有的API的登录进程,该API偶尔会挂起。如果它需要的时间超过,比如说,30秒,我想杀死它并重试(因为它应该只需要2-3秒)

我对终止线程的工作原理,以及终止线程后是否需要加入有点困惑。下面是我的问题,下面是我尝试做的一个例子:

问题:

  • Abort在其调用的线程中引发线程中止异常。那会传播吗?我是否需要在调用线程中显式地处理它,还是该线程刚刚死亡

  • 我是否需要加入一个中止的线程,这样它就不会变成僵尸,或者我只是被*NIX编程世界弄糊涂了

    public static Session GetSession()
    {
        Session session = new Session("user", "pass");
    
        try
        {
            //Create a thread to get the session so we can kill it if it hangs.
            Thread thread = new Thread(() => session.Logon());
    
            //Create a thread to kill the session thread if it hangs.
            Thread watcher = new Thread(() => HangKill(thread));
    
            //Start both threads.
            thread.Start();
            watcher.Start();
    
            //Wait for session thread to finish - abort kill thread if it does.
            thread.Join();
            watcher.Abort();
            watcher.Join();
        }
        catch (Exception ex)
        {            
            status = ex.ToString();
        }
    
        return session;
    }
    
    
    public static void HangKill(Thread t)
    {
        Thread.Sleep(30);
    
        if (t.IsAlive == true)
        {
            t.Abort();
        }
    }
    

  • 在您自己的进程中中止线程是危险的。(尽管在其他进程中也是如此。)线程可能拥有一些锁,可能正在更新关键结构等。因此,这不是解决问题的方法


    我建议将有问题的服务包含到另一个进程中,这样,如果出现问题,您可以终止该进程。使用IPC(共享内存?WCF?)与该进程进行通信。

    Thread.Abort()
    是非常危险的。对于糟糕的编辑,我会提出建议,但我无法将函数名作为代码块的一部分。@SLaks-谢谢,否则我怎么能做到这一点,必须有一个标准方法:)没有。在没有合作的情况下中止任务本质上是不安全的,因为你不知道自己在干什么。是的,这是有道理的。谢谢,谢谢。这似乎是非常沉重的重量,只是想超时的日志上挂起虽然。难道没有办法从父线程(创建者)杀死线程吗?或者我必须走C版本的线程定时等待、信令和条件变量的路线吗?@w00te:no,实际上没有有效的方法。对不起。线程可以通过跳转到threads函数端来安全地终止自身,但这是您所能做的最大限度。如果线程挂起在你不拥有的代码中,这就没用了。哈哈,好吧。我想我完蛋了。我可以问一下,在同样的情况下,你会怎么做(不一定是你认为的最佳实践?@w00te:好吧,如果你需要运行的代码不安全*崩溃、挂起等等),我会在它周围筑起一堵墙,周围有锁和武装警卫——也就是说,在另一个进程中运行它。一种更轻量级的方式可以是使用AppDomains(您可以卸载一个),但它可能太高级了,不能在上面浪费时间。@w00te:无论如何,在任何环境中,无论是本机环境还是托管环境,让崩溃/挂起的代码尽可能远离您的代码运行都是一个好主意。