Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在使用backgroundWorker的过程中停止实施_C#_Loops_Backgroundworker_Cycle - Fatal编程技术网

C# 如何在使用backgroundWorker的过程中停止实施

C# 如何在使用backgroundWorker的过程中停止实施,c#,loops,backgroundworker,cycle,C#,Loops,Backgroundworker,Cycle,所以,这段代码使用随机起始数获取递增数流的值。如果start1的值大于start2,我想用文本框显示对应的行,否则显示另一行 问题是我不能停止程序,直到给定的周期数不满足。按钮在植入过程中挂起。我理解这种情况发生的原因是一个循环。现在我试图用backgroundWorker停止它,但我得到了相同的结果,“取消”按钮以相同的方式挂起 我希望与位于backgroundWorker1\u ProgressChanged内的backgroundWorker一起使用的代码。我真的不太明白这里发生了什么。也

所以,这段代码使用随机起始数获取递增数流的值。如果start1的值大于start2,我想用文本框显示对应的行,否则显示另一行

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

我希望与位于backgroundWorker1\u 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可以做什么的好示例。基本上,您的代码只是休眠一点,然后报告进度,在另一个线程中几乎没有用处

添加1000 textBox1.AppendText后,您的backgroundWorker1_ProgressChanged相当繁重,因此可能需要一些时间

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

当您在UI线程上考虑BeaBeWorks1Pro进程被执行时,无论您在取消上进行多少次点击,都不会被处理,直到BealWorkWork1PosirrsSechange返回。所有UI处理都必须由UI线程完成。应该指出的是,在此期间后台工作线程也被挂起,不幸的是,它是测试取消的代码的唯一部分。即使ReportProgress是异步的,您仍然需要UI线程处理cancel button click事件并将工作标记为CancellationPending

<> P>我建议你不要在后台进行一次报告,一步一步的改变,或者考虑报告将项目添加到文本框中作为批次。 这样,您就不会大量使用消息泵,应用程序的响应速度也会更快

将您的backgroundWorker1\u ProgressChangedobject发件人ProgressChangedEventArgs e更改为将批次用作:

由于您的ProgressChanged处理程序在每次ReportProgress调用中都忙于更新UI大约1000次,因此它将使用所有UI线程CPU时间,并且该线程将永远无法处理Cancel按钮,因为它已经太忙了

考虑到您使用的是BackgroundWorker,您应该在DoWork处理程序中移动大部分ProgressChanged,并在后台线程中删除睡眠

顺便说一句,你使用后台软件没有任何意义。UI线程应该尽可能少地执行任务,而后台线程应该尽可能多地执行任务。在您的情况下,在后台线程中睡眠是没有意义的,因为后台工作不依赖于所经过的时间

移动代码后,需要将数据发送回UI线程。但这很容易,因为ReportProgress的重载允许将任何.NET对象传递给UI线程,假设后台工作线程是从UI线程创建的,通常情况下就是这样。另一方面,您可以简单地将用户数据强制转换为适当的类型,并使用该信息将适当的文本附加到文本框中


通过改进代码,您应该能够更快地处理数据。顺便说一下,还应该使用StringBuilder来构建字符串。事实上,它应该会对UI性能产生显著影响,因为您更新UI文本的次数会减少1000次。

除了我的答案之外,您还可以查看该页面上的相关部分以获取有用的信息。显然,上面的实现非常糟糕,并且对BackgroundWorker的工作方式理解很差。我的性能非常差,不确定该怎么做,如果我将代码放在backgroundWorker1上,而不是放在worker上。ReportProgress就这样,我很怀疑这一点。你认为什么会更快?一条追加文本还是1000条追加文本?大部分CPU时间都花在AppendText上,即使调用堆栈来自另一个线程后台工作程序的ReportProgress
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());