I have a Windows Forms
application. This application will run some processes that take a while to run, so I would like to run them in parallel. Here's a little of what I'm trying to implement.
In the form constructor, I create a generic list ( ProcessViewModel
) of objects called Processes
, with some information pertinent to each execution.
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 using the ProcessObject
method, which in turn will perform heavy processing (various statistical calculations). So I go through this list of processes and review 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 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 process operants 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 type InvalidOperationException
.
Is there any way to perform heavy processing and send a asynchronously to an IU without interrupting the processing?
I know that in .Net, there are several resources for concurrent programming like Threads
, Parallels
and async/await
, Task
, but I'm not sure which one to use so that my application can scale the best way. I do not know if what I'm doing is the best way.