System.ComponentModel.BackgroundWorker

发布于 2024-10-09 21:54:43 字数 2144 浏览 5 评论 0原文

有人可以解释一下为什么我遇到backgroundworker的问题

backgroundWorker1_RunWorkerCompleted工作得很好并将文本发送到textbox1 但 backgroundWorker1_DoWork 不起作用! 它应该将文本“Working...”发送到 textbox1,但我收到错误 textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now +@" >>" +str;

我收到的错误与跨线程有关,

有人可以帮忙吗?

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;
            }
        }

can some one explain why I face problem with backgroundworker

backgroundWorker1_RunWorkerCompleted works just fine and sends the text to the textbox1
but
backgroundWorker1_DoWork does not work!
it should to send the text "Working..." to the textbox1, but I get error with
textBox1.Text = textBox1.Text + Environment.NewLine + DateTime.Now +@" >> " +str;

the error I get is related to Cross-Thread

any one can help?

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)
        {

        }

    }
}

Edit

I seems able to solve the issue with:

is this solution a proper way? or it is a dirty workaround and I should not do it!?!

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;
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

是你 2024-10-16 21:54:43

这是设计使然。 DoWork() 在另一个线程上运行,不应使用任何 GUI 组件。在调试模式下,他会立即被发现并被困住。

如果您在调试器之外运行它,它(几乎总是)会工作。但很少会出现问题,这是很难发现的错误。

基本上,您的输出应该类似于:

    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;
        }
    }

另外,您应该在 Completed 事件处理程序中检查 e.Error

This is by design. DoWork() runs on another Thread and should not use any GUI components. In Debug mode his is immediately spotted and trapped.

If you run this outside of the debugger it will (almost always) work. But very rarely things will go wrong, a hard to catch bug.

Basically, your output should look something like:

    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;
        }
    }

Also, you should check e.Error in the Completed eventhandler.

氛圍 2024-10-16 21:54:43

“DoWork”事件处理程序是您在后台线程上执行工作的地方。在该线程上,您不应直接访问 UI。

“RunWorkerCompleted”事件处理程序在 UI 线程上执行。

通常,要从 UI 线程报告进度,您需要为 ProgressChanged 注册一个事件处理程序,并从后台线程调用 ReportProgress。或者,您可以使用Control.Invoke/Control.BeginInvoke,但是您并没有真正从使用BackgroundWorker<中获得太多好处。 /code> 首先。

The "DoWork" event handler is meant to be where you do the work on the background thread. On that thread, you shouldn't access the UI directly.

The "RunWorkerCompleted" event handler is executed on the UI thread.

Usually to report progress from the UI thread, you register an event handler for ProgressChanged and call ReportProgress from the background thread. Alternatively, you can use Control.Invoke/Control.BeginInvoke but then you're not really getting much benefit from using BackgroundWorker in the first place.

丘比特射中我 2024-10-16 21:54:43

您得到的错误到底是什么?

该文本框可能需要调用。

What exactly is the error you get?

It is possible, that this textBox needs invocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文