【发布时间】:2012-10-12 00:04:56
【问题描述】:
我正在设计一个小程序,其目标是确保我们的一个服务器启动并运行。在某些情况下,服务器不会应答,必须启动脚本来重新启动服务器。
首先,我启动了一个负责获取信息的新线程,然后主线程将其加入一定的时间跨度。然后我中止线程以断开连接并最终加入它以留出足够的时间来执行 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 等变量已在别处声明,并且已知运行良好。我想我的问题来自秒表声明/初始化之后的三行。首先,我必须说我从一个类似的应用程序中复制粘贴了这些行,但基本上它应该只从给定的命令中获取结果。不幸的是,因为我在危急情况下无法调试,所以我不知道哪一行有问题,但无论如何,似乎 ThreadAbortException 没有效果。是因为代码已被关闭为非托管吗?
我在这里迷路了,所以欢迎任何想法!谢谢!
【问题讨论】:
-
Thread.Abort 最好避免。在很多情况下调用可能会导致问题...请参阅文档:msdn.microsoft.com/en-us/library/ty8d3wta.aspx 如果可能,请向您的线程发出信号,表明该停止并让它优雅地完成。
-
好吧,我希望我可以。但是如果异常不起作用,什么样的信号才能起作用呢?
标签: c# multithreading threadabortexception