我有一个包含多个WPF项目的Visual Studio解决方案,主项目启动一个WPF应用程序,该应用程序充当其他项目的父/网关,在导航主应用程序窗口上的菜单后有一个按钮用于启动另一个显示MS Access DB信息的应用程序。从主应用程序启动辅助应用程序的代码如下(为简单起见,更改了一些名称/路径):
private void OpenDatabase(object sender, RoutedEventArgs e)
{
ShowInTaskbar = false; // prevents parent app from showing in taskbar
Process DBAPP = new Process();
DBAPP.StartInfo.FileName = "path\to\DBAPP.exe";
DBAPP.Start();
DBAPP.WaitForExit();
ShowInTaskbar = true; // parent app now shows in taskbar
}
辅助数据库应用程序具有ShutdownMode=“OnExplicitShutdown”,然后在mainWindow.cs(而不是App.xaml(.cs))中,我有一个关闭按钮的处理程序,如下所示:
private void CloseMainMenu(object sender, RoutedEventArgs e)
{
Close();
Application.Current.Shutdown();
}
当我关闭辅助应用程序时,我返回到第一段代码,在ShowInTaskbar = true;
行看到一个错误,上面写着“System.ComponentModel.Win32Exception:'配额不足,无法处理此命令'“
我只看到这个错误时,我有次要的应用程序运行超过约3-5分钟-可能是数据库连接或窗口本身使用的资源;如果我快速打开辅助应用程序并立即关闭它-返回到主应用程序-我没有看到这个错误。
1条答案
按热度按时间trnvg8h31#
我花了几乎一整天的时间来研究这个问题,然后才终于弄明白了这个问题。这是一个很头疼的问题,所以我想把我的答案放在这里来帮助别人。
从阅读其他帖子上(here和here以及无数其他)我发现,当从派生进程返回到调用者进程时,存在需要清除的消息队列。阻塞调用Process.WaitForExit后直接返回()可能不允许在调用方进程之前清除消息队列-特别是在已经过了很长时间的情况下为了解决这个问题,可以将Process.WaitForExit()调用放到它自己的线程中;我在下面的代码示例中看到了here和。
本质上,我们所做的是在启动派生进程后,启动一个新线程,该线程的唯一工作是处理Process.WaitForExit()的返回,然后死亡。如果我们有一个每500 ms不断检查线程是否活着的循环,那么在线程死亡和调用方进程试图恢复执行之间有足够的缓冲区,以便清除消息队列;因此没有更多错误。
我最初看到的错误后,约3-5分钟,但没有看到它与衍生进程运行超过30分钟,并处理许多数据库操作。我会考虑这个解决方案。