Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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/6/multithreading/4.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#_Multithreading_Winforms - Fatal编程技术网

C# 如何使用BackgroundWorker在运行时创建和添加控件

C# 如何使用BackgroundWorker在运行时创建和添加控件,c#,multithreading,winforms,C#,Multithreading,Winforms,我不知道如何使用WinForms中的BackgroundWorker使用单独的线程实现方法。 我希望此方法(每次单击按钮后)执行: 创建ProgressBar(前一个下的每个新的) 创建位图和BackgroundWorker 使用BackgroundWorker在单独的线程中设置位图中每个像素的颜色 在进度栏上显示进度 完成后:使用位图在后台创建一个新表单 完成后:卸下进度条 我的代码: List<BackgroundWorker> Workers; List&l

我不知道如何使用WinForms中的BackgroundWorker使用单独的线程实现方法。 我希望此方法(每次单击按钮后)执行:

  • 创建ProgressBar(前一个下的每个新的)
  • 创建位图和BackgroundWorker
  • 使用BackgroundWorker在单独的线程中设置位图中每个像素的颜色
  • 在进度栏上显示进度
  • 完成后:使用位图在后台创建一个新表单
  • 完成后:卸下进度条
我的代码:

    List<BackgroundWorker> Workers;
    List<ProgressBar> Progress;
    int OperationsCount = 0;
    private void ShowProgress(int n, int percent)
    {
        Progress[n].Value = percent;
    }
    private void Blend(object sender, DoWorkEventArgs e)
    {
        Bitmap BlendedImage = ... // creates a bitmap
        for (int i = 0; i < BlendedImage.Width; i++)
        {
            for (int j = 0; j < BlendedImage.Height; j++)
            {
                ... //changing colour of every pixel
            }
            this.Invoke(new Action(()=>ShowProgress((int)e.Argument, (int)(100 * (double)(i/BlendedImage.Width)))));
        }

        Form BlendedImage_Form = new Form();
        BlendedImage_Form.Size = new Size(BlendedImage.Width, BlendedImage.Height);
        BlendedImage_Form.BackgroundImage = BlendedImage;
        BlendedImage_Form.BackgroundImageLayout = ImageLayout.Stretch;
        this.Invoke(new Action(() => BlendedImage_Form.Show()));

    }        
    private void PerformBlending_Button_Click(object sender, EventArgs e)
    {
        int n = OperationsCount++;
        Progress.Add(new ProgressBar());
        Progress[n].Size = ...
        Progress[n].Location = ...
        Progress[n].Maximum = 100;
        this.Controls.Add(Progress[n]);

        Workers.Add(new BackgroundWorker());
        Workers[n].DoWork += new DoWorkEventHandler(Blend);
        Workers[n].RunWorkerCompleted += (object _sender, RunWorkerCompletedEventArgs _e) => 
        {
            //OperationsCount--;
            //Progress[n].Dispose();
            //this.Controls.Remove(Progress[n]);
            //Progress.RemoveAt(n);
        };
        Workers[n].RunWorkerAsync(n);
    }
列出工人名单;
列出进度;
整数运算计数=0;
私有void ShowProgress(整数n,整数百分比)
{
进度[n]。值=百分比;
}
私有void混合(对象发送方,DoWorkEventArgs e)
{
位图BlendedImage=…//创建位图
对于(int i=0;iShowProgress((int)e.Argument,(int)(100*(double)(i/BlendedImage.Width)()));
}
Form BlendedImage_Form=新表单();
BlendedImage_Form.Size=新尺寸(BlendedImage.Width、BlendedImage.Height);
BlendedImage_Form.BackgroundImage=BlendedImage;
BlendedImage_Form.BackgroundImageLayout=ImageLayout.Stretch;
调用(新操作(()=>BlendedImage_Form.Show());
}        
私有void PerformBlending按钮单击(对象发送者,事件参数e)
{
int n=操作计数++;
Progress.Add(新的ProgressBar());
进度[n]。大小=。。。
进度[n]。位置=。。。
进度[n]。最大值=100;
此.Controls.Add(进度[n]);
添加(新BackgroundWorker());
工人[n].DoWork+=新的DoworkerVenthandler(混合);
Workers[n]。RunWorkerCompleted+=(对象\u发送方,RunWorkerCompletedEventArgs\u e)=>
{
//操作计数--;
//进程[n].Dispose();
//此.Controls.Remove(进度[n]);
//进展。移除(n);
};
Workers[n].RunWorkerAsync(n);
}
当我只点击一次按钮时,一切似乎都很好,但当我点击两次按钮时,程序:

  • 创建正确显示进度的第一个进度条,并正确显示新表单和位图
  • 创建第二个进度条,但它根本不显示进度,并且不显示任何窗体和位图

PS我宁愿使用BackgroundWorker而不是其他工具。

根据您的评论,这里是解决方案

 public void DoSomething()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(()=> DoSomething()));
            }
            else
            {
               // update the ui from here, no worries
            }
        } 
在这段代码中,我正在修改主线程上的对象。如果从非UI线程进行的调用将进入InvokeRequired

//根据您在注释中给出的代码


请尝试在调用内部创建实例。它应该可以工作。

在哪里实例化这些列表?所有UI工作都应该在主线程上。即使您正在使用BackgroundRoker,也需要修改主线程上的控件。@Groo in public main window()(double)(i/BlendedImage.Width)是一个标准的C#bug,它总是生成0。你必须要求浮点除法,((double)i/BlendedImage.Width)@Adrian那么改变像素颜色后如何返回位图呢?我需要它在我的表单中显示它