我需要从一个WPF/C #用户界面运行并查看我们系统中的一些慢的bat文件。用户界面不应该等待进程结束,而是在bat文件中发生任何事情时显示它。
下面的代码现在可以工作,但引入了一个线程来处理它。
private void OnClick(object sender, RoutedEventArgs e)
{
Thread thread1 = new Thread(() =>
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.WorkingDirectory = "C:\my\folder\with\batfile";
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C run.bat";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.EnableRaisingEvents = true;
p.OutputDataReceived += P_OutputDataReceived;
p.Start();
p.BeginOutputReadLine();
p.WaitForExit(20000);
}
);
thread1.Start();
}
private void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
lvConsoleOutput.Dispatcher.Invoke(() =>
{
m_ConsoleRows.Add(e.Data);
});
}
}
注意:lvConsoleOutput
是与m_ConsoleRows
相关联的常规列表视图,m_ConsoleRows
是可观察集合。
示例run.bat文件的内容如下:
echo 1
echo 2
timeout 2
echo more text 3
timeout 1
echo almost the end
timeout 3
echo DONE!
如果不在线程中运行,整个UI将冻结,直到整个bat文件运行完成。然后我在UI中得到输出,它再次解冻。使用上面的thread1
,我得到了实现的结果,但是...
我的问题是:
我可以不引入线程来完成此操作吗?
是否有更清洁的方法来实现这一目标?
1条答案
按热度按时间mlmc2os51#
如果不在线程中运行,整个UI将冻结,直到整个bat文件运行完成。
这是因为
WaitForExit
调用。删除它即可:需要注意的是,由于您直接访问列表框,因此您并不一定需要ObservableCollection作为其ItemsSource,这样做也可以使用较少的代码: