5
I have an app Windows Forms. This application will perform some processes that take some time to execute, so I would like to run them in parallel. Follows a little of what I’m trying to implement.
In the form builder, I create a generic list (ProcessViewModel) of objects called Processes, with some information relevant to each implementation.
private List<ProcessViewModel> Processes { get; set; }
public Form1()
{
InitializeComponent();
Processes = new List<ProcessViewModel>();
for(int i = 0; i < 10; i++)
{
Processes.Add(new ProcessViewModel()
{
Id = i,
Process = "Process " + i,
Status = "Stopped",
Progress = 0,
Max = 3000
});
}
}
When the user clicks a button, I will start about 10 processes through the method ProcessObject, which in turn will perform a heavy processing (several statistical calculations). So I go through this list of processes and pass it on as an argument to an asynchronous method.
private async void button1_Click(object sender, EventArgs e)
{
// esta lista contém 10 objetos que servem como parametros para cada processo
foreach (var process in Processes)
await ProcessObject(process);
}
In my asynchronous method I get the argument and I will perform this operation that contains a loop and in this loop (my processing) and I would like to notify the progress of this processing to an interface.
private async Task ProcessObject(ProcessViewModel process)
{
process.Status = "Starting";
await Task.Run(()=>
{
process.Progress = 0;
do
{
process.Status = "Running";
// aqui entra meu processamento pesado
// gostaria de atualizar meu objeto aqui
process.Progress++;
// feedback para interface
UpdateRow(process);
} while (process.Progress < process.Max && /*outra condição estatística*/);
});
}
As I will have 10 operating processes at the same time, I thought of doing a grid, as in the image below:

This is the method that updates a grid with the progress information of each activity.
private void UpdateRow(ProcessViewModel process)
{
dataGridView1.Rows[process.Index - 1].Cells[1].Value = process.Progress;
dataGridView1.Refresh();
}
It turns out that when it comes time to update the interface, I’m getting an exception of the type InvalidOperationException.
Is there any way to perform a heavy processing and send a asynchronous feedback to an UI, without interrupting the processing?
I know that on . Net, there are several features for concurrent programming such as Threads, Parallels and async/await, Task, but I’m not sure which one to use so my app can climb the best way. I don’t know if what I’m doing is the best way.
What is this
Processand consequently theprocess? "when it comes time to update the interface" is vague. Try to put more information to help understand the whole. Theasyncseems to me to be a suitable solution, and really it needs to be used carefully with UI.– Maniero
I’ll edit my question, thanks @bigown
– Felipe Oriani
Some helpful links: http://stackoverflow.com/questions/17972268/async-await-with-a-winforms-progressbar, http://simplygenius.net/Article/AncillaryAsyncProgress, http://blogs.msdn.com/b/dotnet/archive/2012/06/async-in-4-5-enabling-progressand-cancellation-in-async-Apis.aspx, http://www.codeproject.com/Tips/729674/Simple-Net-progress-bar-using-async-await, http://codereview.stackexchange.com/questions/20820/use-and-understanding-ofasync-awaitin-net-4-5, http://www.danderson.me/posts/async-and-awaitui-synchronization-with-c-5-net-4-5-and-winforms/
– Maniero
I changed my question, see if it was clearer what I’m trying rs. Thanks @bigown
– Felipe Oriani
One way would be using
Delegatesto update your UI. Have some knowledge aboutDelegates?– Marciano.Andrade
@Andrade, Yes, I usually work with
Action<>andFunc<>, but is there a way to implement this asynchronously? How could I?– Felipe Oriani