サーバーの1つが稼働していることを確認することを目的とした小さなプログラムを設計しています。場合によっては、サーバーが応答せず、スクリプトを起動してサーバーを再起動する必要があります。
最初に、情報を取得する役割を担う新しいスレッドを開始します。その後、特定の期間、メイン スレッドが参加します。次に、スレッドを中止して切断し、最後にスレッドに参加して、キャッチを実行し、最後にブロックするのに十分な時間を残します。
理論的にはうまくいくはずです: タイムスパンが十分に短い場合、実際にサーバーがダウンしていることを示します (割り当てられた短いタイムスパンで接続を確立できなかったため)。しかし、場合によっては、サーバーが実際にダウンしている場合でも、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 などの変数は別の場所で宣言されており、適切に機能することがわかっています。私の問題は、ストップウォッチの宣言/初期化に続く3行に及ぶと思います。まず、同様のアプリケーションからこれらの行をコピーして貼り付けたと言わざるを得ませんが、基本的には、指定されたコマンドから結果のみをフェッチする必要があります。残念ながら危機的状況でデバッグできなかったので、どの行が問題なのかはわかりませんが、とにかく ThreadAbortException は効果がないようです。コードがアンマネージドに切り替えられたためですか?
私はここで迷子になっているので、どんなアイデアでも歓迎します! ありがとう!