ooTheDomeoo - Do 27.08.09 14:32
Titel: synchronisieren / warten auf asynchronen Prozess
Hallo, ich habe folgendes Problem und komme einfach nicht mehr weiter.
Ich möchte einen externen Process aus .NET heraus starten und auf die Ausgabe warten. Die Ausgabe passiert asynchron. Damit ich auf entsprechende Aufgabeparameter warten und reagieren kann.
Problem dabei ist, das mein Programmfluss solange warten muss, bis das ergebnis da ist. Dies bekomme ich einfach nicht gelöst.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130:
| public class ProcessHandler {
private System.Diagnostics.Process _cmd = null; public event EventHandler OutputEvent; public event EventHandler ErrorEvent;
private string _processName = String.Empty; private string _processParameter = String.Empty;
private string _lastOutputLine = String.Empty; public string LastOutputLine { get { return _lastOutputLine; } set { _lastOutputLine = value; } }
private string _lastCommandLine = String.Empty; public string LastCommandLine { get { return _lastCommandLine; } set { _lastCommandLine = value; } }
public string LastErrorLine { get { return _lastErrorLine; } set { _lastErrorLine = value; } }
public ProcessHandler(string processName) { _processName = processName;
}
public ProcessHandler(string processName, string processParameter) { _processName = processName; _processParameter = processParameter;
} public void Start() { try { _cmd = new System.Diagnostics.Process(); _cmd.StartInfo.FileName = _processName;
if (!_processParameter.Equals("")) { _cmd.StartInfo.Arguments = _processParameter; }
_cmd.StartInfo.RedirectStandardInput = true; _cmd.StartInfo.RedirectStandardOutput = true; _cmd.StartInfo.RedirectStandardError = true;
_cmd.StartInfo.CreateNoWindow = true; _cmd.StartInfo.UseShellExecute = false;
_cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(OutputDataHandler); _cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ErrorDataHandler);
_cmd.Start(); _cmd.StandardInput.AutoFlush = true; _cmd.BeginOutputReadLine(); _cmd.BeginErrorReadLine(); } catch(System.ComponentModel.Win32Exception) { throw new Exception("Der Prozess konnte nicht gestartet werden."); }
}
public void Stop() { _cmd.Close(); _cmd = null; }
public void Execute(string command) { _lastCommandLine = command; _cmd.StandardInput.WriteLine(command); _cmd.StandardInput.Flush(); }
private void OutputDataHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs outLine) { if (!String.IsNullOrEmpty(outLine.Data)) { OnOutputEvent(EventArgs.Empty); } }
private void ErrorDataHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs errorLine) { if (!String.IsNullOrEmpty(errorLine.Data)) { _lastErrorLine = errorLine.Data; } }
} |
die Aufrufende Methode in einer andren Klasse würde z.B. so aussehen
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| private void Test() { ProcessHandler cmd = new ProcesssHandler("cmd"); cmd.Execute(ping 127.0.0.1);
} |
Mir stellen sich dabei folgende Problem:
- wie Warte ich mit dem Programmablauf auf das Ergebnis
- wie gebe ich das Ergebnis an die Aufrufende Methode zurück ....
(ping) ist nur ein Beispiel, ich will damit beliebige Programme steuern. ping dient zur zum testen
Ich hoffe ihr habt eine Idee für mich.
Moderiert von
Christian S.: Highlight- durch C#-Tags ersetzt
Lossy eX - Do 27.08.09 16:08
Hallo. Ich muss schon sagen. Dein Beitrag ist gefährdet mein Augelicht. ;) Für Code gibt es hier entsprechende Tags.
Aber zu deiner Frage. Da kann ich dir nur wärmstens die MSDNs empfehlen. Fort findest du unter anderem
alle Member von Process [
http://msdn.microsoft.com/de-de/library/system.diagnostics.process_members%28VS.80%29.aspx]. Also alle Eigenschaften und Methoden die die Klasse zu bieten. Sowie auch Details zu den einzelnen Membern. Unter anderem auch von
WaitForExit [
http://msdn.microsoft.com/de-de/library/system.diagnostics.process.waitforexit%28VS.80%29.aspx]. Mit WaitForExit kannst du laut msdns auf das Beenden deines Prozesses warten. Entweder so lange bis er geschlossen wurde oder eine gewisse Anzahl an Millisekunden. Denn wenn du so lange wartest bis die anderen Anwendung zu ist, dann kann es gut passieren, dass deine Anwendung Sekunden/Minuten nicht mehr reagiert. Wenn du aber nur eine gewisse Zeit wartest, dann könntest du dafür sorgen, dass deine Anwendung noch reagiert bzw wäre dein Programm noch in der Lage notfalls den anderen Prozess abzuschießen.