Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 执行远程连接的线程赢得';流产_C#_Multithreading_Threadabortexception - Fatal编程技术网

C# 执行远程连接的线程赢得';流产

C# 执行远程连接的线程赢得';流产,c#,multithreading,threadabortexception,C#,Multithreading,Threadabortexception,我正在设计一个小程序,其目标是确保我们的一台服务器已启动并运行。在某些情况下,服务器不会应答,必须启动脚本才能重新启动服务器 首先,我将启动一个负责获取信息的新线程,然后主线程将其连接一段时间。然后,我中止线程以断开连接,并最终加入它,以便留出足够的时间来执行catch并最终阻塞 从理论上讲,它应该工作得很好:如果时间跨度足够短,它确实表明服务器已停机(因为在分配的短时间跨度内无法建立连接)。但在某些情况下,当服务器真的停机时,程序将继续执行,就好像ThreadAbortException没有效

我正在设计一个小程序,其目标是确保我们的一台服务器已启动并运行。在某些情况下,服务器不会应答,必须启动脚本才能重新启动服务器

首先,我将启动一个负责获取信息的新线程,然后主线程将其连接一段时间。然后,我中止线程以断开连接,并最终加入它,以便留出足够的时间来执行catch并最终阻塞

从理论上讲,它应该工作得很好:如果时间跨度足够短,它确实表明服务器已停机(因为在分配的短时间跨度内无法建立连接)。但在某些情况下,当服务器真的停机时,程序将继续执行,就好像ThreadAbortException没有效果一样。问题是,这些停机时间是非常零星的,所以我无法亲自调试它,以查看哪些工作不正常

事情是这样的:

这是主线程,调用工作线程。非常简单

public void LaunchCommand()
{
    Thread pingThread = new Thread(new ThreadStart(Ping));
    pingThread.Start();
    while (!pingThread.IsAlive);
    pingThread.Join(new TimeSpan(0, 0, _maxTime)); 
    pingThread.Abort(); //  Time's up.
    pingThread.Join();  //  Make sure we complete everything before moving on
}
这就是所谓的线程:

private void Ping()
{
    try
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        serviceType = Type.GetTypeFromProgID(serviceProgID, _server, true);
        service = Activator.CreateInstance(serviceType);
        _xmlResult = ApxServiceType.InvokeMember("ExecuteXML", BindingFlags.InvokeMethod, null, service, new string[] { _dataset, Command, string.Empty }) as string;

        stopwatch.Stop();
        _latency = stopwatch.Elapsed;

        // Trivial validations to make sure _status is true, such as _xmlResult.Contains(certainSubString); and such

        _status = true;     //  Everything seems to work fine if we could make up to here.
    }
    catch (ThreadAbortException)
    {
        Console.WriteLine("Server timeout :(");
        return;
    }
    catch (Exception e)
    {
        Console.WriteLine("Server exception: " + e.Message);
        return;
    }
    finally
    {
        if (!_status)
        {
            _latency = new TimeSpan(0, 0, _maxTime);
        }
    }
}
诸如Commands、serviceProgID等变量已在别处声明,并且已知其工作良好。我想我的问题来自stopwatch声明/初始化之后的三行。首先,我必须说我从一个类似的应用程序复制粘贴了这些行,但基本上它应该只从给定的命令中获取一个结果。不幸的是,因为我无法在紧急情况下进行调试,我不知道哪一行有问题,但无论如何,ThreadAbortException似乎没有效果。是否因为代码已关闭为非托管


我在这里迷路了,任何想法都欢迎!谢谢

实际上,我不认为需要为您的场景使用单独的线程。您可以使用同步操作检查服务器的可用性。用于检查服务器可用性的功能是否提供超时选项?如果是,那么超时选项就足够了。如果函数在超时之前返回,则表示服务器处于联机状态,否则服务器将关闭

如果用于检查服务器可用性的函数不提供超时选项,并且可能导致线程永远等待(或等待很长时间),则可以使用新线程。但是,如果
Thread.Join(Timeout)
方法返回true,并且
\u status
变量也为true,则可以确定服务器处于联机状态。如果
Thread.Join(Timeout)
返回false,则表示服务器已关闭


作为一种良好的实践,您应该在catch块处理中止异常中使用
Thread.ResetAbort
。否则,一旦catch块完成执行,运行时将重新引发ThreadAbort异常。

我实际上认为没有必要为您的场景使用单独的线程。您可以使用同步操作检查服务器的可用性。用于检查服务器可用性的功能是否提供超时选项?如果是,那么超时选项就足够了。如果函数在超时之前返回,则表示服务器处于联机状态,否则服务器将关闭

如果用于检查服务器可用性的函数不提供超时选项,并且可能导致线程永远等待(或等待很长时间),则可以使用新线程。但是,如果
Thread.Join(Timeout)
方法返回true,并且
\u status
变量也为true,则可以确定服务器处于联机状态。如果
Thread.Join(Timeout)
返回false,则表示服务器已关闭


作为一种良好的实践,您应该在catch块处理中止异常中使用
Thread.ResetAbort
。否则,一旦catch块完成执行,运行时将重新引发ThreadAbort异常。

最好避免Thread.Abort。在许多情况下,呼叫可能会导致问题。。。查看文档:如果可能的话,向你的线程发出停止的信号,让它优雅地结束。好吧,我希望我可以。但是,如果异常不起作用,什么样的信号将使作业生效?最好避免Thread.Abort。在许多情况下,呼叫可能会导致问题。。。查看文档:如果可能的话,向你的线程发出停止的信号,让它优雅地结束。好吧,我希望我可以。但是,如果一个例外不起作用,什么样的信号会使工作?嗨,谢谢你的回答。我认为你是对的:但是我不确定它是否解决了我的问题,因为流氓线程将继续运行。但我想这不是一个
系统.Environment.Exit
无法处理的问题。无论如何,再次感谢,如果它能帮我解决问题,我一定会给你一个很好的复选标记。嗨,谢谢你的回答。我认为你是对的:但是我不确定它是否解决了我的问题,因为流氓线程将继续运行。但我想这不是一个
系统.Environment.Exit
无法处理的问题。无论如何,再次感谢你,如果它能帮我解决问题,我一定会给你一个很好的复选标记。