System.ComponentModel.BackgroundWorker - PullRequest
       1

System.ComponentModel.BackgroundWorker

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

может кто-нибудь объяснить, почему я сталкиваюсь с проблемой с фоновым работником

backgroundWorker1_RunWorkerCompleted работает просто отлично и отправляет текст в textbox1 но backgroundWorker1_DoWork не работает! он должен отправить текст «Working ...» на textbox1, но я получаю сообщение об ошибке с textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now + @ ">>" + str;

ошибка, которую я получаю, связана с Cross-Thread

Кто-нибудь может помочь?

cheesr

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace FolderWatchingGUI01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        public void output(string str)
        {
            textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now +@"  >>  " +str;
        }


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            output("Working ...");
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            output("Work Completed");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button2.Enabled = true;
            button1.Enabled = false;
            output("Starting Work");
            backgroundWorker1.RunWorkerAsync();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
            output("Work Canceld");
            button2.Enabled = false;
            button1.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }
}

Редактировать

Кажется, я могу решить проблему с:

это правильное решение? или это грязный обходной путь, и я не должен этого делать!?!

delegate void outputCallback(string text);


        public void output(string str)
        {
            if (textBox1.InvokeRequired)
            {
                outputCallback d = output;
                Invoke(d, new object[] { str });
            }
            else
            {
                textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now +@"  >>  " +str;
            }
        }

Ответы [ 3 ]

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

Это по замыслу. DoWork () работает в другом потоке и не должен использовать какие-либо компоненты графического интерфейса. В режиме отладки его сразу обнаруживают и ловят.

Если вы запустите это вне отладчика, оно будет (почти всегда) работать. Но очень редко что-то пойдет не так, трудно поймать ошибку.

По сути, ваш вывод должен выглядеть примерно так:

    public void output(string str)
    {
        if (this.InvokeRequired)
        {
            var act = new Action<string>(output);
            this.Invoke(act, str);
        }
        else
        {
            textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now + @"  >>  " + str;
        }
    }

Кроме того, вы должны проверить e.Error в обработчике событий Completed.

1 голос
/ 27 декабря 2010

Обработчик события «DoWork» предназначен для того места, где вы выполняете работу в фоновом потоке .В этом потоке вы не должны обращаться к интерфейсу напрямую.

Обработчик события "RunWorkerCompleted" выполняется в потоке интерфейса.

Обычно, чтобы сообщить о ходе выполнения из потока интерфейса, вы регистрируетеобработчик событий для ProgressChanged и вызов ReportProgress из фонового потока.В качестве альтернативы, вы можете использовать Control.Invoke / Control.BeginInvoke, но при этом вы не получите большой пользы от использования BackgroundWorker во-первых.

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

Какую именно ошибку вы получаете?

Возможно, этот textBox нуждается в вызове.

...