2012-01-27 24 views
3

外部サードパーティパッケージを実行するプロセスを開始しています。このプロセスの出力を監視するために、数秒ごとにイベントを発生させるタイマーを起動したいと考えています。ここで私は、プロセスを開始するために使用するコードは次のとおりです。プロセスを起動してイベントを監視して監視します

Process process = new Process(); 
process.StartInfo.FileName = exe; 
process.StartInfo.Arguments = args; 
process.StartInfo.CreateNoWindow = true; 
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
process.StartInfo.UseShellExecute = false; 
process.StartInfo.RedirectStandardError = true; 
process.StartInfo.RedirectStandardOutput = true; 
process.Start(); 
process.BeginErrorReadLine(); 
RuntimeMonitor rtm = new RuntimeMonitor(OutputFile(), InputFile(), 5000); 
process.WaitForExit(); 
rtm.Close(); 

ランタイムモニタのコンストラクタは次のとおりです。

public RuntimeMonitor(string _outfile, 
         string _title, 
         double intervalMs) // in milliseconds 
{ 
    outFile = outfile; 
    title = _title; 
    timer = new System.Timers.Timer(); 
    timer.Interval = intervalMs; 
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_func); 
    timer.AutoReset = true; 
    timer.SynchronizingObject = null; 
    timer.Start(); 
} 

私は取得しています症状がtimer_funcは、プロセスが終了するまで呼び出されないということである(すなわち後process.WaitForExit();完了)。私はタイマ経過イベントが非同期に発生したと思ったが、ロックされているようだ。

EDIT:よく見知らぬ人になる。私はtimer.SynchronizingObjectをヌルに設定しようとしましたが、役に立たなかった。私はまた、System.Threading.Timerクラスを使ってみましたが、同じ結果を得ました。

もう1つの情報。プロセスからのデータ収集を開始するよう呼びかけますが、関連性があるかどうかはわかりません(上記のコードでBeginErrorReadLineコール)。

+0

WaitForExitはメインスレッドを中断しますが、System.Timerはメインスレッド上でのみ実行されます。したがって、非同期で待機するか、新しいスレッドでタイマーを実行することができます。 –

+1

WaitForExitを使用する代わりに、アプリケーションを実行したままにして、タイマーが呼び出されるたびにProcess.HasExitedブールをチェックしてください。 –

+0

私は別のスレッドでタイマーを実行すると、行く方法だと思っています。あなたは私にそれをする方法を教えてもらえますか? –

答えて

2

タイマーが起動していないようです。私はあなたのコードを取り出し、これを試して試してみるために少し構造化しました。次のコードは正常に動作します。おそらくあなたはあなたの仕事を得るためにそれを使うことができます。

void Main() 
{ 
    Process process = new Process(); 
    process.StartInfo.FileName = "notepad.exe"; 
    process.StartInfo.CreateNoWindow = true; 
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardError = true; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.Start(); 
    RuntimeMonitor rtm = new RuntimeMonitor(5000); 
    process.WaitForExit(); 
    rtm.Close(); 
} 

public class RuntimeMonitor 
{ 
    System.Timers.Timer timer; 

    // Define other methods and classes here 
    public RuntimeMonitor(double intervalMs) // in milliseconds 
    { 
     timer = new System.Timers.Timer(); 
     timer.Interval = intervalMs; 
     timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_func); 
     timer.AutoReset = true; 
     timer.Start(); 
    } 

    void timer_func(object source, object e) 
    { 
     Console.WriteLine("Yes"); 
    } 

    public void Close() 
    { 
     timer.Stop(); 
    } 
} 
0

私はあなたのコードは、あなたがRuntimeMonitorコンストラクタ内のタイマーを作成することを示しているが、念のために知っている - あなたのタイマーのTimer.SynchronizingObjectプロパティをチェックし、それがnullであることを確認してください。そうでなければ、あなたの状況を説明するかもしれません。デザイナでTimerを使用するとプロパティも設定されます - MSDNから:

WindowsフォームデザイナでVisual Studio内でTimerを使用すると、SynchronizingObjectは自動的にTimerを含むコントロールに設定されます。たとえば、フォームを継承するForm1のデザイナーにTimerを配置すると、TimerのSynchronizingObjectプロパティがForm1のインスタンスに設定されます。

関連する問題