【问题标题】:How to wait for form to load, then start method?如何等待表单加载,然后启动方法?
【发布时间】:2012-09-08 05:57:40
【问题描述】:

我有一个 WPF 应用程序,它在加载时执行一个方法来检查某些文件是否存在,如果不存在,则下载它们。它还下载一个字符串用作消息,并输出到in-app 控制台。

但是,当我启动程序时,我看到白屏几秒钟,然后窗口加载,一切都完成了。所以看起来该方法是在窗口加载之前执行的。

如何等待窗口加载,等待大约 2 秒,然后运行该方法?

这是我尝试运行的方法的代码:

consolemessage("STARTUP", "Verifying existence of essential files...");
if(!File.Exists("Interop.NATUPNPLib.dll"))
    Download("link here", "Interop.NATUPNPLib.dll");
if(!File.Exists("LICENSE.txt"))
    Download("link here", "LICENSE.txt");
consolemessage("STARTUP", "Essential file validation completed!");

【问题讨论】:

  • 建议不要使用硬编码的时间间隔进行多线程处理。在另一台机器上运行代码,它可能会中断。我会尝试在窗口的 Loaded 事件中调度加载,优先级为 Background。

标签: c# wpf multithreading


【解决方案1】:

如果您看到几秒钟的白屏,这意味着您的任务(下载文件)需要几秒钟。您可以在窗口加载后通过订阅窗口的“Loaded”事件来启动此任务,但它仍会冻结应用程序 3 秒。

您必须创建一个适合您需要的解决方案,以便以用户友好的方式处理此任务。

如果您想在检索到此信息之前阻止用户使用应用程序,您可以创建一个带有加载动画或进度条的弹出窗口。您可以为这些设置动画,因为您的任务有时间完成。

如果您希望用户能够在后台加载信息时使用您的应用程序,您需要使用诸如 BackgroundWorker 或其他异步设计之类的东西将信息加载到另一个线程上,然后回调主线程时信息已准备好并已加载。如果您正在使用 Web 请求,您通常可以通过使用诸如“BeginGetResponse”之类的异步重载将它们转换为异步 Web 请求。这取决于您的代码。

编辑

您可以像这样在 Window 范围内创建 BackgroundWorker:

public partial class MainWindow : Window
{
    private BackgroundWorker worker;

    public MainWindow()
    {
        InitializeComponent();

        Loaded += MainWindow_Loaded;
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
        consolemessage("STARTUP", "Verifying existence of essential files...");
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        if (!File.Exists("Interop.NATUPNPLib.dll"))
            Download("link here", "Interop.NATUPNPLib.dll");

        if (!File.Exists("LICENSE.txt"))
            Download("link here", "LICENSE.txt");
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // Signal your UI that the files are now available here if needed.
        consolemessage("STARTUP", "Essential file validation completed!");
    }
}

【讨论】:

  • 谢谢,但我之前几乎没有做过很多线程 - bgworker 将如何完成?
  • 谢谢,由于某种原因,它运行该方法 3 次,我做错了什么?
  • 不应该。您是否正在创建放入对象的多个实例?例如,您是否将代码放入 UserControl 中,然后在窗口中创建该 UserControl 3 次?
  • 我现在修好了,谢谢。我不需要这个:Loaded += MainWindow_Loaded;
  • 我明白了,您一定已经在 Visual Studio 设计器中订阅了该事件。
【解决方案2】:

您还可以在 Form.Loaded 事件中启动一个单次计时器,延迟 100 毫秒左右,然后在其中运行您的方法。这就是我过去所做的,以便在我运行我的代码之前让表单完全加载。

示例:

public partial class MainWindow : Window
{
    System.Windows.Threading.DispatcherTimer oneShot = new System.Windows.Threading.DispatcherTimer();
    public MainWindow()
    {
        InitializeComponent();
        oneShot.Interval = new TimeSpan(0, 0, 0, 0, 100);
        oneShot.Tick += new EventHandler(oneShot_Tick);
    }

    void oneShot_Tick(object sender, EventArgs e)
    {
        oneShot.Stop();

        // Your Code or Method here
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        oneShot.Start();
    }
}

【讨论】:

  • 谢谢,这将在未来派上用场!
【解决方案3】:

您可以将代码放在Window_Loaded 事件中。这是一个快速而肮脏的实现,不会冻结您的 UI(请记住,如果用户可以在它们实际完成之前尝试引用这些东西,它可能会引发异常,在这种情况下使用 Moozhe 的解决方案来创建某种加载屏幕)

在顶部使用:

using System.Threading;

简单代码:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Thread t = new Thread( YourMethod);
    t.IsBackground = true;
    t.Start();
}
void YourMethod()
{
    consolemessage("STARTUP", "Verifying existence of essential files...");
    if (!File.Exists("Interop.NATUPNPLib.dll"))
        Download("link here", "Interop.NATUPNPLib.dll");
    if (!File.Exists("LICENSE.txt"))
        Download("link here", "LICENSE.txt");
    consolemessage("STARTUP", "Essential file validation completed!");
}

【讨论】:

  • @user1588364 你是在同一个线程上运行进程吗?也许发布一些导致问题的代码。另外你确定你在window_loaded而不是构造函数中吗?
  • 我在 Window_Loaded 中。但它在同一个线程上运行。生病将我的代码添加到问题中。
  • @user1588364 好的,听起来您可以将长时间运行的逻辑放到另一个线程中,它会解决您的问题,无需等待。
  • @user1588364 我感觉正在尝试执行需要此信息的某些东西,但由于尚未填充它而失败。定义停止工作?它会抛出异常吗?
  • 也不例外。我必须构建并运行,因为在过去的几天里由于一些奇怪的原因没有调试选项是 Visual Studio。不在菜单或工具栏中。
猜你喜欢
  • 2019-12-08
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多