I have been reading up on the async/await syntax introduced in .Net 4.5 and getting a feel of it.
I have found simple samples where Task.Yield is the way to go rather than Application.DoEvents. I tried one of the samples (filling in the blanks)
Code on Form1 with 1 button:
public async void button1_Click(object sender, EventArgs e) {
var list = new List<int>();
for (int i = 0; i < 10000; i++) {
list.Add(i);
}
for (int i = 0; i < list.Count; i++) {
Process(list[i]);
await Task.Yield();
//await Task.Delay(1);
}
}
public static void Process(int i) {
Debug.WriteLine(i);
}
However, running this code, the UI thread is blocked or I believe it is blocked as I can not move the window while the code runs. If I comment out the Task.Yield() and use the Task.Delay(1) line instead, the GUI is responsive.
So have I misunderstood something here? I know using DoEvents and the like is bad practice, but I have some legacy code I am responsible for that uses this, and I aim to replace it with Yield as it is the best choice. But first I need to get warm with async/await.
async
doesn't magically make your code good.Yield
is not a direct replacement forDoEvents
(which is evil). It will take some work to change the alignment of your code.As long as you don't need the UI context, you can just push your work off to the threadpool:
Alternatively, you can consider breaking up the UI-specific parts either using
IProgress<T>
or usingTask.Run
for the non-UI work: