2

我有一个 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!");
4

3 回答 3

4

如果您看到白屏几秒钟,这意味着您的任务(下载文件)需要几秒钟。您可以在窗口加载后通过订阅窗口的“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!");
    }
}
于 2012-09-07T15:56:57.713 回答
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();
    }
}
于 2012-09-07T16:00:36.427 回答
1

您可以将代码放在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!");
}
于 2012-09-07T15:31:39.550 回答