C# 使用IProgress从任务列表中的多个任务更新多个进度条<;T>;

C# 使用IProgress从任务列表中的多个任务更新多个进度条<;T>;,c#,asynchronous,C#,Asynchronous,我有多个任务将并行运行。它们被收集在一个任务列表中。每个任务都有一个与之关联的进度条。我一直在尝试实现iprogressapi,以便在任务运行时更新进度条。但是,进度条仅在任务完成时更新 我有一组模拟我的问题的测试代码,无论我如何修改它,任务栏只会在任务完成时更新 创建每个任务时,我传递将更新右侧进度条的进度对象。此进度对象将传递给内部任务,以便在每个循环中更新。Progress.Report()方法将检查所需的invokererequired,尽管我认为如果将IProgress API与异步方

我有多个任务将并行运行。它们被收集在一个任务列表中。每个任务都有一个与之关联的进度条。我一直在尝试实现iprogressapi,以便在任务运行时更新进度条。但是,进度条仅在任务完成时更新

我有一组模拟我的问题的测试代码,无论我如何修改它,任务栏只会在任务完成时更新

创建每个任务时,我传递将更新右侧进度条的进度对象。此进度对象将传递给内部任务,以便在每个循环中更新。Progress.Report()方法将检查所需的invokererequired,尽管我认为如果将IProgress API与异步方法一起使用,则不需要这样做

我已经包括了代码。表单只有一个按钮(button1)启动所有流程,并且有11个进度条,每个任务都应该更新进度条

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }        

    private async void button1_Click(object sender, EventArgs e)
    {
        List<ProgressBar> listOfProgressBars = new List<ProgressBar>
            {
                progressBar1,
                progressBar2,
                progressBar3,
                progressBar4,
                progressBar5,
                progressBar6,
                progressBar7,
                progressBar8,
                progressBar9,
                progressBar10,
                progressBar11
            };

        List<Task<bool>> taskList = new List<Task<bool>>();
        foreach (ProgressBar pBar in listOfProgressBars)
        {
            pBar.Value = 0;
            pBar.Minimum = 0;
            pBar.Maximum = 100;
        }

        int i = 11;
        for (int j = 1; j <= i; j++)
        {
            ProgressBar thisProgressBar = listOfProgressBars[j - 1];
            var progress = new Progress<int>((int value) =>
            {
                UpdateProgressBar(thisProgressBar, value);
            });

            taskList.Add(InnerProcess(j, progress));
        }

        await Task.WhenAll(taskList);

    }

    public void UpdateProgressBar(ProgressBar pBar, int value)
    {
        if (this.InvokeRequired)
        {
            this.EndInvoke(this.BeginInvoke(new MethodInvoker(delegate() { UpdateProgressBar(pBar, value); })));
        }
        else
        {
            pBar.Value = value;
        }
    }

    public Task<bool> InnerProcess(int waitTime, IProgress<int> progress)
    {
        return Task<bool>.Run(() =>
            {
                var job = new LongJob();
                job.Delay(waitTime, progress);
                return true;
            });
    }

    class LongJob
    {
        public void Delay(int i, IProgress<int> progress)
        {
            for (int j = 1; j <= i; j++)
            {
                Thread.Sleep(500);
                if (progress != null)
                {
                    progress.Report(j/i*100);
                }
            }
        }
    }
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}        
私有异步无效按钮1\u单击(对象发送方,事件参数e)
{
ListListOfPressBars=新列表
{
progressBar1,
progressBar2,
progressBar3,
progressBar4,
progressBar5,
progressBar6,
progressBar7,
进度条8,
第9条,
progressBar10,
progressBar11
};
List taskList=新列表();
foreach(ProgressBars列表中的ProgressBar pBar)
{
pBar.值=0;
pBar.最小值=0;
pBar.最大值=100;
}
int i=11;
对于(int j=1;j
{
UpdateProgressBar(thisProgressBar,值);
});
添加(InnerProcess(j,progress));
}
等待任务。WhenAll(任务列表);
}
public void UpdateProgressBar(ProgressBar pBar,int值)
{
if(this.invokererequired)
{
this.EndInvoke(this.BeginInvoke(新方法调用程序(委托(){UpdateProgressBar(pBar,value);}));
}
其他的
{
pBar.值=值;
}
}
公共任务InnerProcess(int waitTime,IProgress progress)
{
返回任务。运行(()=>
{
var job=new LongJob();
作业延迟(等待时间、进度);
返回true;
});
}
班长
{
公共无效延迟(int i,i进度)
{
对于(int j=1;j
j/i
是整数除法,因为j在完成之前小于i,
j/i
是0


将j转换为浮点,所有结果都应该是好的

由于整数除法,进度计算中存在错误。将其更改为:

progress.Report((int)(((double)j) / i * 100));

您是正确的,
Progress
在创建当前同步上下文时捕获该上下文,并使用该上下文调用回调。此处需要使用
invokererequired
/
BeginInvoke
progress.Report((int)(((double)j) / i * 100));