gpt4 book ai didi

c# - 我如何使代码等到 bool 信号继续

转载 作者:行者123 更新时间:2023-12-03 13:20:06 25 4
gpt4 key购买 nike

我创建了WPF应用程序,然后通过删除app.xaml并将构 build 置为类库将其转换为DLL。我正在使用C#Windows窗体来测试DLL。 WPF DLL已预加载,因此以后可以调用它以立即显示和显示,而不必等待加载。我要完成的工作是调用Show(ShowWPFApp)并让代码等待,直到通过调用WPFAppResponse翻转 bool 值为止(此操作是通过初始加载传递的)。我现在拥有的方式导致UI冻结。关于如何使UI等待而不冻结UI的任何想法?

Windows窗体调用WPF DLL

namespace WindowsFormsDLLTest
{
public partial class Form1 : Form
{
WPFDLL.LoadWPFApp wpfApp = null;
public Form1()
{
InitializeComponent();
}

private void btnLoadWPFApp_Click(object sender, EventArgs e)
{
wpfApp = new WPFDLL.LoadWPFApp();
try
{
wpfApp.Load();
}
catch (Exception ex)
{

}
}

private void btnShowWPFApp_Click(object sender, EventArgs e)
{
try
{
string result = null;
result = wpfApp.ShowWPFApp("John Doe");
}
catch (Exception ex)
{

}
}
}
}

WPF DLL应用
namespace WPFDLL
{
public class LoadWPFApp
{
private Application application = null;
private MainWindow mainWindow = null;
private bool waitOnShowWindow {get; set;}
private string returnResults = null;

public void Load()
{
StartLoadingWPFApp();
}

[STAThread]
private void StartLoadingWPFApp()
{
application = new Application();

SplashScreenWindow splashWindow = new SplashScreenWindow();
splashWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
splashWindow.Show();

try
{
mainWindow = new MainWindow(WPFAppResponse);
mainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
splashWindow.Close();

application.Run();
}
catch (Exception ex)
{
splashWindow.Close();
MessageBox.Show("Error starting application:" + Environment.NewLine + ex.ToString(), "WPF App Error", MessageBoxButton.OK, MessageBoxImage.Error);
mainWindow = null;
}
}

public string ShowWPFApp(string person)
{
returnResults = null;
mainWindow.LoadPerson(person);
mainWindow.Show();

while(waitOnShowWindow)
{
//Code waits until bool is set to false
}

return returnResults;
}

public void WPFAppResponse(string person)
{
returnResults = person;
waitOnShowWindow = false;
mainWindow.Hide();
}
}
}

最佳答案

从Windows窗体启动WPF应用很麻烦。您偶然发现了一个相当复杂的线程问题。通常的建议是改为将该WPF应用程序创建为WPF控件库。但是,我看到这可能无法解决您遇到的缓慢加载问题,这就是您制作轻量级WinForms包装器应用程序的原因。

问题是您的循环:

while(waitOnShowWindow)
{
//Code waits until bool is set to false
}

该循环在UI线程上运行,阻止其处理Windows消息。 (如果您不熟悉该概念,请查找它,因为它对于Windows UI内容很重要。)要使UI响应,它必须正在运行Windows消息循环。我看到两个解决方案:
  • 创建您自己的消息循环。
  • 立即返回,然后再获取结果。

  • 解决方案1:
    要创建自己的消息循环,您需要使用Dispatcher.Run()或Dispatcher.PushFrame()之类的东西。试试看,看看是否可行:
    public string ShowWPFApp(string person)
    {
    returnResults = null;
    mainWindow.LoadPerson(person);
    mainWindow.Show();
    Dispatcher.CurrentDispatcher.Run();
    // do whatever to get the results
    return returnResults;
    }

    如果这不起作用,则可能需要改用PushFrame()。在Dispatcher.Run()无法正常工作的情况下,这是一些更深入的文章。
    http://www.codeproject.com/Articles/152137/DispatcherFrame-Look-in-Depth
    http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/

    解决方案2:
    public void ShowWPFApp(string person)
    {
    returnResults = null;
    mainWindow.LoadPerson(person);
    mainWindow.Show();
    }

    现在,该调用将不会阻塞UI线程,并且将显示WPF窗口。 Windows窗体应用程序正在运行消息循环,因此WPF现在可以运行。但是,您如何得到结果呢?由于它现在异步运行,因此您将不得不寻找其他方法来返回返回值。我认为MainWindow类上的事件是最简单的方法。

    另外:[STAThread]属性没有执行任何操作。 [STAThread]仅在应用程序的入口点具有含义。幸运的是,您的Windows窗体应用程序已经将[STAThread]放在Main()方法上,因此您的线程是STA线程。

    关于c# - 我如何使代码等到 bool 信号继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21414713/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com