Process.Start () bleibt hängen, wenn es in einem Hintergrundthread ausgeführt wird
Ich habe den ganzen Tag Probleme behoben. Nach einigem tunForschung und eine Menge Versuch und Irrtum, es scheint, dass ich in der Lage war, das Problem auf die Tatsache einzugrenzen, dass mein Aufruf anprocess.Start()
funktioniert nicht auf einem Timer-Thread. Der folgende Code funktioniert, wenn er auf dem Hauptthread ausgeführt wird. Fügen Sie genau denselben Code in einen Timer-Rückruf ein, und er bleibt hängen. Warum? Wie kann ich mit einem Timer arbeiten?
private static void RunProcess()
{
var process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = "/c exit";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start(); // code hangs here, when running on background thread
process.StandardOutput.ReadToEnd();
process.WaitForExit();
}
BEARBEITEN
Als Test habe ich genau denselben Code auf einem anderen Laptop verwendet und dabei das gleiche Problem festgestellt. Dies ist vollständiger Code, der in eine Konsolen-App eingefügt werden kann.process.Start()
hängt, aber sobald ich eine Taste zum Beenden drücke,process.Start()
wird abgeschlossen, bevor das Programm endet.
private static System.Timers.Timer _timer;
private static readonly object _locker = new object();
static void Main(string[] args)
{
ProcessTest();
Console.WriteLine("Press any key to end.");
Console.ReadKey();
}
private static void ProcessTest()
{
Initialize();
}
private static void Initialize()
{
int timerInterval = 2000;
_timer = new System.Timers.Timer(timerInterval);
_timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
_timer.Start();
}
private static void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
if (!Monitor.TryEnter(_locker)) { return; } // Don't let multiple threads in here at the same time.
try
{
RunProcess();
}
finally
{
Monitor.Exit(_locker);
}
}
private static void RunProcess()
{
var process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = "/c exit";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start(); // ** HANGS HERE **
process.StandardOutput.ReadToEnd();
process.WaitForExit();
}