WMIを使用していくつかのプロセスをリモートで実行しようとしていますが、プロセスが終了するのを待ちます。現在、イベントウォッチャーは準同期を使用WaitForNextEvent
しており、プログラムに何かが発生した場合に備えてタイムアウトもあります。これはすべてうまく機能します。これを非同期イベント処理に変更しようとしましたが、イベントウォッチャーを起動するとアクセス拒否エラーが発生します。準同期方式に固執することができたので、これは大したことではありませんが、1つの例外があります。
何らかの理由で、プログラムの実行中にマシンが再起動、フリーズ、またはネットワーク接続を失った場合、WaitForNextEvent
はタイムアウト例外をスローしませんが、スレッドを無期限にブロックします(応答なしで10分間そのままにしました、タイムアウト30秒でした)。私の質問は、接続に関係なくタイムアウトするために、または非同期アクセス許可にアクセスするためにクライアント側をセットアップするために、イベントウォッチャーを特定の方法でセットアップできるかどうかを誰かが知っていますか。通常、最初のものが優先されますが、2番目のものもオプションです。
ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
new WqlEventQuery(
"select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));
w.Options.Timeout = new TimeSpan(0, 0, 0, 30);
var ev = w.WaitForNextEvent();
ManagementeventWatcherに、接続に関係なく戻るまたはタイムアウトするオプションがあるかどうか、またはイベントをキャプチャするために非同期メソッドを使用できるかどうかを知りたいです。
解決
ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
new WqlEventQuery(
"select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));
w.Options.Timeout = new TimeSpan(0, 0, 0, 0, 1);
DateTime start = DateTime.Now;
while (Status == StatusNotStarted) //default status(just strings)
{
try
{
var ev = w.WaitForNextEvent();
ReturnCode = (uint)ev.Properties["ExitStatus"].Value;
Status = (ReturnCode == 0) ? StatusOk : StatusFailed;
}
catch (ManagementException ex)
{
if (!ex.Message.Contains("Timed out"))
{
throw ex;
}
try
{
Ping p = new Ping();
PingReply reply = p.Send(MachineIP);
if (reply.Status != IPStatus.Success)
{
Status = StatusFailed;
}
else
{
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
if (duration.TotalMilliseconds > Timeout)
{
Status = StatusFailed;
}
}
}
}
}