C #: блокировка всплывающих окон, несмотря на BackgroundWorker - PullRequest
0 голосов
/ 19 августа 2010

Я использую .net 2.0 и создал форму (System.Windows.Forms.Form) для отображения информации во время длительных задач.

Когда я запускаю долгосрочное задание, я создаю новый экземпляр этой формы, вызываю .Show () и запускаю BackgroundWorker.Но даже несмотря на то, что я использую BackgroundWorker для выполнения работы, форма действительно отображается, но сразу же блокируется и не отвечает до тех пор, пока фоновый работник не завершит работу, если форма отображается, но содержимое (gif и текстовое поле)показано?

Странная вещь, это не происходит, когда работа для BackgroundWorker настолько интенсивна!?!Как так?

Пример:

private void UpdateReportingTab()
{
    //p is an instance variable; Progressbar is just a simple form control
    //showing the passed message
    p = new Progressbar("Loading Data...");
    p.Show();
    BackgroundWorker bw = new BackgroundWorker();
    bw.WorkerSupportsCancellation = true;
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    bw.RunWorkerAsync();
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{            
    p.BeginInvoke(new MethodInvoker(p.Close));
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new MethodInvoker(delegate()
        {
            //long running database queries, whose results update text fields
            //while text fields are filled p show "no response"
            TextEditItems.Text = Convert.ToString(itemsDao.getItemCount());
            ....
        }
    }
}

Спасибо!

Andi

Ответы [ 2 ]

3 голосов
/ 19 августа 2010

Потому что вы плохо работаете с фоновым работником, чувак;)

Фоновый рабочий ПРИНЯТ В ГЛАВНУЮ НИТУ - который помещает работу обратно в основной поток пользовательского интерфейса, где.

Вы НЕ ДОЛЖНЫ ИСПОЛЬЗОВАТЬ ОБРАТНО, ЧТО ВАМ НЕОБХОДИМО.

В частности:

  • Сделать длительный запрос к базе данных, получить результаты
  • ТО вызывается обратно в поток пользовательского интерфейса для обновления TextEditItems

В тот момент, когда вы вызываете обратно, вы возвращаетесь в UI THREAD - в вашем случае фоновый работник therad выполняет только возврат назад ... что делает фоновый работник бессмысленным.

2 голосов
/ 19 августа 2010

Используя BeginInvoke, вы фактически выполняете код в потоке пользовательского интерфейса.Ваш BackgroundWorker здесь бесполезен, bw_DoWork немедленно вернется и пользовательский интерфейс будет заморожен.

Если вам нужны данные из элементов управления, извлеките их до того, как запустите BackgroundWorker, и выполняйте работу в потоке BGW вместо вызова Invoke или BeginInvoke

...