2

モーダル mdi の子である Windows フォームがあります。これは、バックグラウンドで激しい作業が行われているときに表示されると想定されているため、ユーザーはその作業が完了するまでコントロールを使用できません。

それは非常に簡単です、ここにコードがあります。

public partial class ProgressForm : Form
{
    private int periodCount = 5;

    public ProgressForm(String message)
    {
        InitializeComponent();
        messageLabel.Text = message;
    }

    public void startThread()
    {
        Thread t = new Thread(new ThreadStart(doWork));
        t.IsBackground = true;
        t.Start();
    }

    void doWork()
    {
        while (true)
        {
            if (periodCount == 5)
            {
                periodCount = 1;
            }
            else
            {
                periodCount++;
            }

            switch (periodCount)
            {
                case 1: periodsLabel.Text = "."; break;
                case 2: periodsLabel.Text = ". ."; break;
                case 3: periodsLabel.Text = ". . ."; break;
                case 4: periodsLabel.Text = ". . . ."; break;
                case 5: periodsLabel.Text = ". . . . ."; break;
            }
        }
    }
}

しかし、PeriodLabel.Text は想定どおりに変更されません。バックグラウンドで何か他のことをしている間に UI を更新するにはどうすればよいですか?

ProgressForm progressForm = new ProgressForm("Your database data is being exported, please wait.");
progressForm.ShowDialog();
progressForm.startThread();
4

2 に答える 2

2

まず、私の謙虚な意見では、あなたはあなたのようにただ糸を捨てるべきではありません。

ベストプラクティスは、BackgroundWorkerスレッドを使用することです。

次に、Show()メソッドを使用して表示するだけなので、フォームはモーダルではありません。モーダルフォームにするには、メソッドを使用してダイアログを作成する必要がありますShowDialog()

正確にフォームがクラッシュする理由については、これからはまったく範囲外です。次の手順に従うことを検討してください。

  1. BackgroundWorkerクラスをインスタンス化します。
  2. BackgroundWorker.DoWork()メソッドに汚い仕事をさせてください。
  3. BackgroundWorker.WorkerReportsProgress = trueデザインのコンポーネントモデルプロパティウィンドウでを設定していることを確認してください。
  4. 必ずメソッドをReportProgress()使用してくださいReportProgress(int)

この質問(C#:個別のスレッドを使用してUIにデータを入力する)と、BackgroundWorkerクラスインスタンスの使用について簡単に説明している私のコードサンプルを参照してください。

注:まだ別の例を探しています。

編集#1

スレッドに関する優れた記事は次のとおりです。C#でのスレッド化。
「原因Jon Skeetはそう言った!.NETのマルチスレッド:はじめにと提案

于 2010-12-18T05:28:14.867 に答える
0

スレッドから BeginInvoke を使用してプロパティを実行するフォームのメソッドを呼び出すのではなく、フォーム要素のプロパティにスレッドから直接アクセスしようとしているために (たとえば、PeriodsLabel.Text を呼び出すとき)、アプリがクラッシュしている可能性があります。アクセスしています。

しかし、これらの種類のものには BackgroundWorker クラスを使用する方が良い/簡単です。

于 2010-12-18T05:51:58.657 に答える