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
Process
and consequently theprocess
? "when it comes time to update the interface" is vague. Try to put more information to help understand the whole. Theasync
seems 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
Delegates
to 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