因此此代码采用具有随机起始编号的递增编号流的值。如果start1的值更大,则start2我想用文本框显示相应的行,否则显示另一行。

问题是,直到不满足给定的循环数,我才能停止程序。按钮仅在植入过程中挂起。我了解发生这种情况的原因是循环。现在,我尝试使用backgroundWorker停止它,但得到相同的结果,取消按钮的挂起方式相同。

我想与位于backgroundWorker1_ProgressChanged内的backgroundWorker一起使用的代码。我真的不太明白这里发生了什么。也许您可以帮助我找出我做错了什么:

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

namespace XX_8_0
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void startAsyncButton_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy != true)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void cancelAsyncButton_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.WorkerSupportsCancellation == true)
            {
                backgroundWorker1.CancelAsync();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; i <= 10; i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    System.Threading.Thread.Sleep(500);
                    worker.ReportProgress(i * 10);
                }
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            var random = new Random();
            var start1 = random.Next(0, 100);
            var start2 = random.Next(0, 100);
            var incrementor1 = start1 > 50 ? -1 : 1;
            var incrementor2 = start2 > 50 ? -1 : 1;
            var cV1 = start1;
            var cV2 = start2;

            for (var i = 0; i < 1000; i++)
            {
                if (cV1 == 101) incrementor1 = -1;
                if (cV1 == 0) incrementor1 = 1;

                if (cV2 == 101) incrementor2 = -1;
                if (cV2 == 0) incrementor2 = 1;

                if (cV1 > cV2)
                {
                    textBox1.AppendText("ID: (" + i + ") CV1: (1): [" + cV1 + "] CV2: (0) [" + cV2 + "]\n");
                }
                else
                {
                    textBox1.AppendText("ID: (" + i + ") CV1: (0): [" + cV1 + "] CV2: (1) [" + cV2 + "]\n");
                }

                cV1 += incrementor1;
                cV2 += incrementor2;
            }
        }
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                resultLabel.Text = "Canceled!";
            }
            else if (e.Error != null)
            {
                resultLabel.Text = "Error: " + e.Error.Message;
            }
            else
            {
                resultLabel.Text = "Done!";
            }
        }
    }
}

最佳答案

注意:我认为您的例子可能不是BackgroundWorker可以做的一个很好的例子。本质上,您的代码只是睡了一会儿然后报告进度,在另一个线程中几乎没有用。



您的backgroundWorker1_ProgressChanged很重,添加了1000个textBox1.AppendText(),因此可能需要一些时间。


  按钮仅在植入过程中挂起。我了解发生这种情况的原因是循环。


当您考虑在用户界面线程上执行backgroundWorker1_ProgressChanged时,无论您点击多少次取消,直到backgroundWorker1_ProgressChanged返回之前,都不会对其进行处理。所有UI处理都必须由UI线程完成。应该指出的是,后台工作线程在这段时间内也被挂起,不幸的是,它是代码中测试取消的唯一部分。即使ReportProgress不同步,您仍然需要UI线程来处理“取消”按钮的单击事件并将工作标记为CancellationPending

我建议您不要一次报告backgroundWorker1_ProgressChanged太多,或者考虑考虑批量报告向textBox1添加项目。

这样一来,您就不会淹没消息泵,并且您的应用程序将具有更高的响应速度。

更改您的backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)以将批处理用作:

var builder = new StringBuilder();

for (var i = 0; i < 1000; i++)
{
    if (cV1 == 101) incrementor1 = -1;
    if (cV1 == 0) incrementor1 = 1;

    if (cV2 == 101) incrementor2 = -1;
    if (cV2 == 0) incrementor2 = 1;

    if (cV1 > cV2)
    {
        builder.Append("ID: (" + i + ") CV1: (1): [" + cV1 + "] CV2: (0) [" + cV2 + "]\n");
    }
    else
    {
        builder.Append("ID: (" + i + ") CV1: (0): [" + cV1 + "] CV2: (1) [" + cV2 + "]\n");
    }

    cV1 += incrementor1;
    cV2 += incrementor2;
}

textbox1.AppendText(builder.ToString());

关于c# - 如何使用backgroundWorker在过程中停止实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39339792/

10-11 07:46