What makes you be so confident that WM_PAINT
and other Windows messages are pumped while Parallel.For
or Task.Wait
is blocking on the UI thread?
The following simple example proves you're wrong. The form is not getting repainted to red for the whole 15 seconds, while Parallel.For
is working.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFroms_21681229
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
this.Shown += MainForm_Shown;
}
void MainForm_Shown(object sender, EventArgs e)
{
MessageBox.Show("Before");
this.BackColor = Color.FromName("red");
this.Invalidate();
// the form is not getting red for another 15 seconds
var array = new double[] { 1, 2, 3 };
Parallel.For(0, array.Length, (i) =>
{
System.Threading.Thread.Sleep(5000);
Debug.Print("data: " + array[i]);
});
MessageBox.Show("After");
}
}
}
Here is how to run the tasks in parallel, while keeping the UI responsive:
async void MainForm_Shown(object sender, EventArgs e)
{
MessageBox.Show("Before");
this.BackColor = Color.FromName("red");
this.Invalidate();
// the form is not getting red for another 15 seconds
var array = new double[] { 1, 2, 4 };
var tasks = array.Select((n) => Task.Run(()=>
{
Thread.Sleep(5000);
Debug.Print("data: " + n);
}));
await Task.WhenAll(tasks);
MessageBox.Show("After");
}
You could have done something like await Task.Factory.StartNew(() => Parallel.For(...))
, but that would use at least one more thread than really needed.
To understand what's going on behind the scene here, you'd need to understand how WinForms message loop works inside Application.Run
, how await
yields the execution control back to the message loop and then gets continued via WindowsFormsSynchronizationContext
, when the task has completed. The async-await
tag wiki could help, it contains links to some great, must-read resources.
If you're interested to know how message pumping works during blocking operations, check this answer.