C# 使用IProgress从任务列表中的多个任务更新多个进度条<;T>;
我有多个任务将并行运行。它们被收集在一个任务列表中。每个任务都有一个与之关联的进度条。我一直在尝试实现iprogressapi,以便在任务运行时更新进度条。但是,进度条仅在任务完成时更新 我有一组模拟我的问题的测试代码,无论我如何修改它,任务栏只会在任务完成时更新 创建每个任务时,我传递将更新右侧进度条的进度对象。此进度对象将传递给内部任务,以便在每个循环中更新。Progress.Report()方法将检查所需的invokererequired,尽管我认为如果将IProgress API与异步方法一起使用,则不需要这样做 我已经包括了代码。表单只有一个按钮(button1)启动所有流程,并且有11个进度条,每个任务都应该更新进度条C# 使用IProgress从任务列表中的多个任务更新多个进度条<;T>;,c#,asynchronous,C#,Asynchronous,我有多个任务将并行运行。它们被收集在一个任务列表中。每个任务都有一个与之关联的进度条。我一直在尝试实现iprogressapi,以便在任务运行时更新进度条。但是,进度条仅在任务完成时更新 我有一组模拟我的问题的测试代码,无论我如何修改它,任务栏只会在任务完成时更新 创建每个任务时,我传递将更新右侧进度条的进度对象。此进度对象将传递给内部任务,以便在每个循环中更新。Progress.Report()方法将检查所需的invokererequired,尽管我认为如果将IProgress API与异步方
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));