Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.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/7/sqlite/3.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#Winform ProgressBar和BackgroundWorker_C#_Winforms_Progress Bar_Backgroundworker - Fatal编程技术网

C#Winform ProgressBar和BackgroundWorker

C#Winform ProgressBar和BackgroundWorker,c#,winforms,progress-bar,backgroundworker,C#,Winforms,Progress Bar,Backgroundworker,我有以下问题: 我有一张名为MainForm的表格。我需要在这张表格上做一个长时间的手术 当这个长操作进行时,我需要在MainForm的顶部显示另一个名为ProgressForm的 ProgressForm包含一个进度条,在执行长操作时需要更新该进度条 长时间操作完成后,ProgressForm应自动关闭 我编写了以下代码: using System; using System.Collections.Generic; using System.Text; using System.Window

我有以下问题:

我有一张名为MainForm的表格。我需要在这张表格上做一个长时间的手术

当这个长操作进行时,我需要在MainForm的顶部显示另一个名为ProgressForm的

ProgressForm包含一个进度条,在执行长操作时需要更新该进度条

长时间操作完成后,ProgressForm应自动关闭

我编写了以下代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ClassLibrary
{
    public class MyClass
    {
        public static string LongOperation()
        {
            Thread.Sleep(new TimeSpan(0,0,30));

            return "HelloWorld";
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BackgroungWorker__HelloWorld
{
    public partial class ProgressForm : Form
    {
        public ProgressForm()
        {
            InitializeComponent();
        }

        public ProgressBar ProgressBar
        {
            get { return this.progressBar1; }
            set { this.progressBar1 = value; }
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ClassLibrary;

namespace BackgroungWorker__HelloWorld
{
    public partial class MainForm : Form
    {
        ProgressForm f = new ProgressForm();

        public MainForm()
        {
            InitializeComponent();  
        }

        int count = 0;
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (f != null)
            {
                f.ProgressBar.Value = e.ProgressPercentage;
            }

            ++count;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled) 
            {  
                MessageBox.Show("The task has been cancelled");  
            }  
            else if (e.Error != null)  
            {                  
                MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());  
            }  
            else 
            {  
                MessageBox.Show("The task has been completed. Results: " + e.Result.ToString());  
            }
        }


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (f == null)
            {
                f = new ProgressForm();
            }

            f.ShowDialog();

            //backgroundWorker1.ReportProgress(100);

            MyClass.LongOperation();

            f.Close();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();

            this.Close();
        }
    }
}
我找不到更新
progressBar
的方法

我应该将
backgroundWorker1.ReportProgress()
放在哪里?我应该如何称呼它


我不能在
MyClass
中做任何更改,因为我不知道会发生什么,也不知道在我的应用程序的这一层中完成操作需要多长时间


有人能帮我吗?

一个问题是你睡了30秒。通常,您会在长时间运行的任务中的不同点调用
ReportProgress
。因此,为了演示这一点,您可能希望将代码更改为睡眠1秒,但每次睡眠结束时都要调用30次
ReportProgress


另一个问题是,您正在从后台线程显示
ProgressForm
。您应该在UI线程中启动它,但将后台工作人员的
ProgressChanged
事件挂接到它。然后,当后台工作人员报告进度时,进度表将被更新。

ReportProgress是您必须在“工作”方法中调用的方法。 此方法将引发“ProgressChanged”事件

在表单中,可以将eventhandler附加到ProgressChanged事件。在该eventhandler中,您可以更改progressbar的位置。
您还可以将eventhandler附加到RunWorkerCompleted事件,在该eventhandler中,您可以关闭包含progressbar的表单。

应该注意,您需要设置

backgroundWorker1.WorkerReportsProgress = true;
如果希望后台工作程序引发ProgressChanged事件,则

backgroundWorker1.WorkerSupportsCancellation = true;
如果您希望能够取消工作线程

正如其他人所说,在UI线程中运行f.ShowDialog(),并使用ProgressChanged更新ProgressWindow


要使ProgressForm自动关闭,请在backgroundWorker1_RunWorkerCompleted中调用f.close();这意味着长时间的操作已经完成,我们可以关闭窗口。

这里需要的不是将整个主窗体传递给类,而是只传递BackgroundWorker的实例!您需要将发件人强制转换为后台工作人员,如下所示:

private void bgWorker_DoWork(object sender DoWorkEventArgs e)
{
    // Get the BackgroundWorker that raised this event
    BackgroundWorker worker = sender as BackgroundWorker;

    // And now you just send worker to whatever class you need like so:
    bgArgs args = e.Argument as bgArgs;
    MyClass objMyClass = new MyClass();

    MyClass.MyMethod(strValue, args.Option, worker);

    // Do something based on return value.
}
然后在
MyClass.MyMethod()
中,您可以进行进度计算,只需启动
worker.ReportProgress(int percentage)
事件即可更新主UI表单上的进度条或其他内容

这应该是完美的

查看这篇MSDN文章以了解更多详细信息,请参阅他们的Fibonacci示例,这是因为
CalculateBonacci
是一个向主窗体的UI发送更新的自定义类


有关更多详细信息,请参阅。

我不能对MyClass进行任何更改。因为,我不知道在我的应用程序的这一层会发生什么。那么你就不能准确地报告进度了。我的意思是你可以在
ProgressForm
中添加一个计时器,使进度条每秒递增一次,但这只会产生错觉。如果你无法了解实际进度,那么进度条有多有用?我想这是一个通用的解决方案。请再次阅读问题。从UI线程调用ProgressWindow有什么好处?