如何等待表单加载,然后启动方法?

时间:2012-09-07 15:29:59

标签: c# wpf multithreading

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

3 个答案:

答案 0 :(得分:4)

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

您必须创建一个解决方案,以满足您以如何以用户友好的方式处理此任务的需求。

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

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

修改

您可以在窗口范围内创建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!");
    }
}

答案 1 :(得分: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!");
}

答案 2 :(得分:1)

您还可以在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();
    }
}