The problem is that rendering the picture box requires your application to process its messages. When you're doing long blocking operations on the UI thread, it's impossible for the form to redraw itself (you're blocking the only thread that can do the drawing).
The simplest solution would be to avoid doing any significant work (and/or blocking) on the UI thread. You're reading a CSV file - that's likely going to be an I/O-limited operation. If you use asynchronous I/O to handle the file reading, you'll avoid blocking on synchronous I/O. Using await
makes this rather simple:
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
// Do your work
}
If the CPU-part of the work is also intensive, this will still cause your animation to "stutter". To handle this, you can make sure the whole loading and processing is done without marshalling back to the UI thread (and only going back to the UI thread when you absolutely have to). One way to do that would be using ConfigureAwait
:
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
{
// Do your work
}
Note that you'll probably want to separate the code that happens without access to the UI in a separate method - that will enable you to marshall back to the UI thread just by await
ing that method in turn.
Note that just like Application.DoEvents
, this opens your code to reentrancy. However, given that you've apparently used that before, it shouldn't pose a lot of issues. The usual multi-threading warnings apply if you use ConfigureAwait(false)
, of course - you need to maintain proper synchronization etc.