2

I'm write simple windows application to cal any data,i've done this,open file dialog and read the csv file and finish,anything okay,but i want the change to my application a little,and i want set load animation when file read process,i write this code:

var reader = new StreamReader(File.OpenRead(openFileDialog1.FileName), Encoding.GetEncoding(1256));
LoadForm frm = new LoadForm();

frm.Show();
Application.DoEvents();
while (!reader.EndOfStream)
{
}


and into the Load form i put the picture box and set load gif image,but when i fire the button and load the LoadForm in the that form picture box not animate the image and show me static load gif image,but when i copy that picture box other form,picture box start the load gif animation.
what happen?

behzad razzaqi
  • 1,503
  • 2
  • 18
  • 33
  • You are working with picture Box, you can refer to this: http://stackoverflow.com/questions/165735/how-do-you-show-animated-gifs-on-a-windows-form-c – Drag0nKn1ght May 25 '15 at 06:51
  • my dear friend,please pay attention to my question – behzad razzaqi May 25 '15 at 06:52
  • What are you doing inside while loop? If it's synchronous (and without application.doevents) then picture box won't refresh. I'd move long operations inside a backgroundworker, doevents open your code to reentrancy – Adriano Repetti May 25 '15 at 07:23
  • 2
    The UI thread of your program can do only one thing at a time. Right now it is busy inside that while-loop. Which means that it cannot also keep the picture box animating. You must move the file reading code into a worker thread. Use the BackgroundWorker or Task class. – Hans Passant May 25 '15 at 07:25
  • Thanks,Please Write code of your solution in post @HansPassant – behzad razzaqi May 25 '15 at 07:27
  • 1
    The linked question *does* have the answer to your problem. – Luaan May 25 '15 at 07:28

1 Answers1

1

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 awaiting 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.

Luaan
  • 62,244
  • 7
  • 97
  • 116