正在打开子WPF应用程序并正在返回,没有足够的资源来恢复父WPF应用程序

jrcvhitl  于 2023-03-24  发布在  其他
关注(0)|答案(1)|浏览(152)

我有一个包含多个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分钟-可能是数据库连接或窗口本身使用的资源;如果我快速打开辅助应用程序并立即关闭它-返回到主应用程序-我没有看到这个错误。

trnvg8h3

trnvg8h31#

我花了几乎一整天的时间来研究这个问题,然后才终于弄明白了这个问题。这是一个很头疼的问题,所以我想把我的答案放在这里来帮助别人。
从阅读其他帖子上(herehere以及无数其他)我发现,当从派生进程返回到调用者进程时,存在需要清除的消息队列。阻塞调用Process.WaitForExit后直接返回()可能不允许在调用方进程之前清除消息队列-特别是在已经过了很长时间的情况下为了解决这个问题,可以将Process.WaitForExit()调用放到它自己的线程中;我在下面的代码示例中看到了here和。
本质上,我们所做的是在启动派生进程后,启动一个新线程,该线程的唯一工作是处理Process.WaitForExit()的返回,然后死亡。如果我们有一个每500 ms不断检查线程是否活着的循环,那么在线程死亡和调用方进程试图恢复执行之间有足够的缓冲区,以便清除消息队列;因此没有更多错误。
我最初看到的错误后,约3-5分钟,但没有看到它与衍生进程运行超过30分钟,并处理许多数据库操作。我会考虑这个解决方案。

private void OpenDatabase(object sender, RoutedEventArgs e)
        {
            Process DBAPP = new Process();
            DBAPP.StartInfo.FileName = "path\to\DBAPP.exe";
            DBAPP.Start();
            Thread DBThread = new Thread(() => waitForProcessExit(DBAPP));
            DBThread.Start();
            while (DBThread.IsAlive) Thread.Sleep(500);
        } 

public static bool waitForProcessExit(Process spawnedProc)
        {
            spawnedProc.WaitForExit();
            return true;
        }

相关问题