Prima di tutto, perché non si usa il Process.StandardInput
-property direttamente come bersaglio, come
var process = new Process
{
// all your init stuff
};
var xmlSerializer = new XmlSerializer(data.GetType());
var xmlwriter = XmlWriter.Create(process.StandardInput, xmlWriterSettings);
xmlSerializer.Serialize(xmlwriter, data);
In caso contrario, il msdn-entry dà un howto chiaro per l'utilizzo di Process.BeginOutputReadLine()
, che è possibile rimodellare a
var autoResetEvent = new AutoResetEvent(false); // this mutex acts as our bouncer for the reading-part
var process = new Process
{
// all your init stuff
};
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, args) => {
// TODO you could read the content here with args.Data
autoResetEvent.Set();
};
process.Start();
using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
{
var xmlSerializer = new XmlSerializer(data.GetType());
var xmlwriter = XmlWriter.Create(streamWriter, xmlWriterSettings);
xmlSerializer.Serialize(xmlwriter, data);
}
memoryStream.Position = 0;
using (var streamReader = new StreamReader(memoryStream))
{
while (!streamReader.EndOfStream)
{
var line = streamReader.ReadLine();
process.StandardInput.WriteLine(line);
Console.WriteLine(line);
process.BeginOutputReadLine();
autoResetEvent.WaitOne();
}
}
}
// TODO closing the process.StandardInput, exiting process, ...
In ogni caso - so che questo dovrebbe essere un commento - c'è un motivo specifico per cui stai aspettando che il tuo processo scriva qualcosa?
Il flusso di StandardOutput può essere letto in modo sincrono o asincrono. Metodi come Read, ReadLine e ReadToEnd eseguono operazioni di lettura sincrona sul flusso di output del processo. Queste operazioni di lettura sincrona non vengono completate fino a quando il Processo associato non scrive sul suo stream StandardOutput o chiude il flusso. Al contrario, BeginOutputReadLine avvia le operazioni di lettura asincrona sul flusso StandardOutput . Questo metodo abilita un gestore di eventi designato per l'output del flusso e restituisce immediatamente al chiamante, che può eseguire mentre l'output del flusso viene indirizzato al gestore dell'evento .
Il che significa, che se il processo non scrivere nulla (e si è in attesa), si girano per la risposta senza fine ...
EDIT
Si dovrebbe inoltre aggiungere un gestore a Process.ErrorDataReceived
come
process.StartInfo.RedirectStandardError = true;
process.ErrorDataReceived += (sender, args) => {
// TODO do something with the response of args.Data
autoResetEvent.Set();
};
e
while (!streamReader.EndOfStream)
{
var line = streamReader.ReadLine();
process.StandardInput.WriteLine(line);
Console.WriteLine(line);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
autoResetEvent.WaitOne();
}
per gestire anche casi di errore (qualunque cosa ciò possa significare).
non esiste un metodo per utilizzare direttamente l'istanza di processo come flusso? come 'xs.Serialize (p.StandardInput, data)'? –
Sei sicuro che il lato ricevente stia leggendo i dati? Se il lato ricevente non sta leggendo quando il buffer si riempie, puoi essere bloccato. Hai il codice per il lato ricevente? –
come si incontra la situazione di stallo? Te lo chiedo, perché non c'è il 'lock' - quindi non è del tutto ovvio, per me, come dovrebbe esserci un blocco (che potrebbe essere descritto come un deadlock) ... –