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 要求に変換できます。それはあなたのコードに依存します。

編集

次のように、ウィンドウのスコープで 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.Loaded100 ミリ秒程度の遅延で開始し、その中でメソッドを実行することもできます。これは、コードを実行する前にフォームを完全にロードできるようにするために、過去に行ったことです。

例:

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 に答える