5

アプリケーションが長時間実行されているタスクを実行している間、「お待ちください」winform を「ペイント」したままにするための良い解決策はありますか?

各ステップで form.refresh() を使用してみましたが、長時間実行されるクエリがいくつかあります。これは、これが十分な頻度ではないことを意味します。

基本的にこのSO質問ですが、VSTO(Pythonではなく)を介したExcelのC#で。

4

4 に答える 4

3

statichippoが述べたように、私はBackgroundWorkerクラスを使用します。その目的は、マルチスレッドを簡素化し、ワーカースレッドがGUIをロックせずに時間のかかる処理を実行できるようにすることです。

これがMSDNからの引用です:

BackgroundWorkerクラスを使用すると、別の専用スレッドで操作を実行できます。ダウンロードやデータベーストランザクションなどの時間のかかる操作により、ユーザーインターフェイス(UI)が実行中に応答を停止したように見える場合があります。レスポンシブUIが必要で、そのような操作に関連する長い遅延に直面している場合、BackgroundWorkerクラスは便利なソリューションを提供します。

これは、WindowsフォームでBackgroundWorkerクラスを使用するための優れたチュートリアルです 。BackgroundWorkerクラスを使用してWinFormsにマルチスレッドを実装する

複雑なシナリオでは、C#でマルチスレッドを実装するためのより複雑な方法がありますが、ほとんどの単純なシナリオでは、BackgroundWorkerはうまく機能します(少なくとも私にとっては)。

C#マルチスレッドでGoogleから取得したリンクは次のとおりです
。MSDNスレッドC#でのマルチスレッド
の概要

于 2010-01-19T18:10:25.413 に答える
1

もう 1 つのオプションは、非同期デリゲートを使用してスレッドプール スレッドでフォームを表示することです。

スレッドプール内のスレッドは、アプリケーションの全期間にわたって存続しない、存続期間の短いスレッドに推奨されます。これは短期間の「お待ちください」ウィンドウを表示するためのものであるため、スレッドプールは妥当な選択です。

Action デリゲート (.NET 2.0+) は、その BeginInvoke() メソッドと共に使用され、スレッドプール スレッドでデリゲート コードを自動的に実行します。

いくつかのメモ:

  • ClosePleaseWait() で [お待ちください] フォームを閉じるなど、クロススレッド GUI 呼び出しには Control.BeginInvoke を使用することが重要です。
  • また、m_pleaseWaitForm.ShowDialog();実際には、新しいスレッドで新しいメッセージ ループが開始されます。これにより、Please Wait フォームが有効になります。
  • スレッドプール スレッドが使用されるため、このスレッドは自動的にバックグラウンド スレッドになり、メイン アプリケーションが閉じられると終了します。
  • 別のスレッドで実行する以外に、Form2 について特別なことは何もありません。ピクチャボックス、ラベルなどの子コントロールを配置できます。
  • (MethodInvoker)delegate { ... }デリゲート インラインでコードを実行する .NET 2.0 の方法にすぎません。

以下の例は、Form1: メイン フォームと Form2: Please Wait フォームを含む WinForms プロジェクトに追加できます。

   private Form2 m_pleaseWaitForm = null;

    private void Form1_Shown(object sender, EventArgs e)
    {
        // This code could also be placed in eg. a button click event handler.

        Action<Rectangle> a = new Action<Rectangle>(ShowPleaseWait);

        a.BeginInvoke(this.Bounds, null, null);

        // Do your long running tasks

        ClosePleaseWait();
    }


    private void ShowPleaseWait(Rectangle  bounds)
    {
        // This method runs on the new thread.

        m_pleaseWaitForm = new Form2();

        m_pleaseWaitForm.TopMost = true;
        m_pleaseWaitForm.Location = new Point(bounds.Left + bounds.Width / 2 - m_pleaseWaitForm.Width / 2, bounds.Top + bounds.Height / 2 - m_pleaseWaitForm.Height / 2);

        m_pleaseWaitForm.ShowDialog();

    }

    private void ClosePleaseWait()
    {
        m_pleaseWaitForm.BeginInvoke((MethodInvoker)delegate { m_pleaseWaitForm.Close(); });
    }
于 2010-01-19T17:54:05.997 に答える
0

バックグラウンド ワーカーを使用する

于 2010-01-19T15:04:19.990 に答える
0

C# のコードを使用した良い例を次に示します。

これは特にスプラッシュ スクリーン用ですが、お待ちくださいウィンドウを作成するプロセスはほぼ同じです (おそらく派手な不透明度の一部を差し引いたものです)。

重要な情報は、別のスレッドが必要になるということです。これは物事を複雑にする可能性がありますが、記事はそれを正しく行う方法の良いカバレッジ/例を提供します.

于 2010-01-19T15:19:42.090 に答える