I've been using Progress<T>
and wondered if it can be replaced by Action<T>
.
In the code below, using each of them for reporting progress, i.e. ReportWithProgress()
or ReportWithAction()
, didn't make any noticeable difference to me. How progressBar1
increased, how the strings were written on the output window, they seemed the same.
// WinForm application with progressBar1
private void HeavyIO()
{
Thread.Sleep(20); // assume heavy IO
}
private async Task ReportWithProgress()
{
IProgress<int> p = new Progress<int>(i => progressBar1.Value = i);
for (int i = 0; i <= 100; i++)
{
await Task.Run(() => HeavyIO());
Console.WriteLine("Progress : " + i);
p.Report(i);
}
}
private async Task ReportWithAction()
{
var a = new Action<int>(i => progressBar1.Value = i);
for (int i = 0; i <= 100; i++)
{
await Task.Run(() => HeavyIO());
Console.WriteLine("Action : " + i);
a(i);
}
}
But Progress<T>
can't be a reinvention of the wheel. There should be a reason why it was implemented. Googling "c# Progress vs Action" didn't give me much help. How is Progress different from Action?
HeavyIO
toasync Task HeavyIO() { await Task.Delay(20); }
so that at least you are invoking a Task – FlitchProgress<T>
calls the action in the context in which it was constructed which allows you to interact with the UI without annoying invocation code. – HundredfoldProgress
and how did that fail to answer your question? – DaigleprogressBar1.Value = i
from a different thread results in the dreaded "cross-thread operation not valid" exception. – MalletProgress<T>
is a class, whileAction<T>
is merely a delegate. – Demodena