我有一个以 [STAThread]
启动的控制台应用程序。
该应用程序应打开一个单独的 Wpf UI 以输入一些设置。
相关功能:
private static void openUI()
{
var application = new System.Windows.Application();
//referenced project in the same solution
var ui = new ManagerUI.MainWindow();
//blocks execution
application.Run(ui);
application.Shutdown();
}
首次打开 UI 时如预期的那样工作。 第二次打开 UI 时出现问题。
我得到一个 System.InvalidOperationException
,说明我不能在同一个 AppDomain 中运行多个应用程序实例。
为了节省内存,必须在操作之间关闭它。
我还尝试在构造函数中创建 System.Windows.Application
。
但是当我第二次运行该应用程序时,我得到了一个非常相似的异常。
UI 的 InitializeComponents()
方法抛出一个 System.InvalidOperationException
,表示 Object 将被终止。
StackTraces显示是解析xaml时出现错误,所以我断定打不开,因为第一次执行还是打开了。
无论是调用 ui.Close()
还是调用 application.Shutdown()
都无法解决问题(Environment.Exit()
关闭所有内容,包括我的控制台应用程序)。
ram 分析器表明,并非所有内容都已正确关闭,因为它显示在窗口关闭后比在第一个位置打开之前使用率更高。
如何正确关闭应用程序实例,或者如何重新使用它多次运行 Wpf 应用程序?
最佳答案
查看了 source code for the Application class , 看起来你无法解决这个问题,因为类构造函数初始化了各种静态字段:
public Application()
{
...
lock(_globalLock)
{
if (_appCreatedInThisAppDomain == false)
{
...
_appInstance = this;
...
_appCreatedInThisAppDomain = true;
}
else
{
throw new InvalidOperationException(...);
}
}
}
...
static private object _globalLock;
static private bool _appCreatedInThisAppDomain;
static private Application _appInstance;
...
基本上,构造函数将 _appCreatedInThisAppDomain
设置为 true,并且由于该字段是私有(private)的,您无法将其设置回去*。
我认为实现类似于您想要的东西的唯一方法是编写一个单独的 WPF 应用程序,然后使用 Process 类从您的控制台应用程序启动它。或者,理论上您可以创建一个单独的 AppDomain 来托管您的 WPF 内容,但这会复杂得多。
[*] 除了使用反射,但我们不要去那里!
关于c# - WPF 无法关闭应用程序实例以再次运行它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52894181/