Потоки с модальной формой выполнения, не удается получить свойство текста метки для обновления - PullRequest
2 голосов
/ 18 декабря 2010

У меня есть форма Windows, которая является модальным дочерним элементом mdi, которая должна отображаться, когда происходит какая-то интенсивная фоновая работа, поэтому пользователь не может использовать какие-либо элементы управления, пока эта работа не будет завершена.

Это очень просто, вот код.

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 не меняется, как это и должно быть! Как мне получить его для обновления пользовательского интерфейса при выполнении чего-то еще в фоновом режиме?

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

Ответы [ 2 ]

2 голосов
/ 18 декабря 2010

Во-первых, по моему скромному мнению, вы не должны просто выбрасывать нить, как вы.

Лучшая практика - использовать BackgroundWorker Нить.

Во-вторых, ваша форма совсем не модальная, так как вы показываете ее только методом Show().Чтобы сделать его модальной формой, вам нужно создать диалоговое окно, используя метод ShowDialog().

Почему именно ваша Форма аварийно завершает работу?с этого момента вполне выходит за рамки.Пожалуйста, рассмотрите следующие шаги:

  1. Создание класса BackgroundWorker;
  2. Заставьте метод BackgroundWorker.DoWork() сделать грязную работу за вас;
  3. Убедитесь, чтовы устанавливаете BackgroundWorker.WorkerReportsProgress = true в окне свойств модели компонента в дизайне;
  4. Убедитесь, что вы ReportProgress() используете метод ReportProgress(int).

Пожалуйста, посмотрите этот вопрос (C #: заполнение пользовательского интерфейса отдельными потоками.) и мой пример кода, который, я думаю, просто объясняет использование экземпляра класса BackgroundWorker.

Примечание: Еще ищите другой пример.

РЕДАКТИРОВАТЬ # 1

Вот хорошая статья о потоках: Threading в C # .
'Причина Jon Skeet сказал так! Многопоточность в .NET: Введение и предложения .

0 голосов
/ 18 декабря 2010

Вероятно, что ваше приложение дает сбой, потому что вы пытаетесь получить доступ к свойствам элементов формы непосредственно из потока (например, когда вы вызываете PeriodsLabel.Text), а не используете BeginInvoke из вашего потока для вызова метода в вашей форме, который будет сделать доступ к собственности.

Но лучше и проще использовать класс BackgroundWorker для такого рода вещей.

...