我有一個簡單的控制檯應用程序,可以向標準輸出報告進度。例如:如何根據進程的控制檯輸出更新WPF控件?
static void Main(string[] args)
{
for (int i = 0; i <= 100; i += 10)
{
Console.WriteLine(i);
System.Threading.Thread.Sleep(1000);
}
}
產生以下輸出:
0
10
20
30
40
50
60
70
80
90
100
我想通過.NET Process
調用該應用程序,並更新控制WPF(進度條,具體地)異步:
private void Run()
{
Process process = new Process();
process.StartInfo.FileName = "ConsoleApplication1.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
if (e.Data != null)
{
Console.WriteLine(e.Data);
ProgressBar.Value = double.Parse(e.Data);
}
});
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
process.Close();
}
當我運行它寫入控制檯沒有問題,但可以理解的抱怨嘗試從不同的線程訪問ProgressBar,所以我把它包裝一個調用:
Application.Current.Dispatcher.Invoke(() =>
{
ProgressBar.Value = double.Parse(e.Data);
});
然而,它遇到調用時會凍結。據推測發生了一個僵局,但我不明白爲什麼。
環顧四周,看起來好像Process.SynchronizingObject
被設計來解決這些情況,但我看不到如何使用它從WPF,因爲控件沒有ISynchronizeInvoke
屬性。
如果你聲明類似於'public System.Windows.Threading。Dispatcher dispatch = System.Windows.Threading.Dispatcher.CurrentDispatcher;'當應用程序初始化並使用該調度程序時,它是否會改變行爲? – pay
@pay:無論我在'MainWindow'還是'App'中放置'dispatch'都沒有改變。 –
嗯,所以即使調度器是在UI線程上創建的,它仍然會死鎖?也許可以從該事件處理程序的內部刪除。 – pay