[C#] Help with screenshot code - Disk error when writing too fast

smakme7757

Golden Member
Nov 20, 2010
1,487
1
81
Hi all,

I'm writing/ a piece of software which takes an analysis of a video. It will capture the numberplate of a vehicle and take a screenshot at the same time. So the output is the numberplate and a picture of the vehicle.

It works really well except if we use it on a PC with a single mechanical hard drive we get disk errors when the disk can't keep up with writing the screenshots to disk. To keep the program running i'm made an exception and i just count the amount of disk errors. So the analysis still runs, but we end up missing a few pictures.

To solve the problem we have switched over to an SSD and we don't have any problems, however I'm wondering if maybe there is a way to solve it without forcing users to use an SSD.

It's not a really a problem, but i figured if someone here had an awesome idea i might give it a go :).

Here is the code:
Source

Code:
        public void Capture(Control ctrl, string fileName)
        {
            Rectangle bounds = ctrl.Bounds;
            Point pt = ctrl.PointToScreen(bounds.Location);
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(new Point(pt.X - ctrl.Location.X, pt.Y - ctrl.Location.Y), Point.Empty, bounds.Size);
            }

            bitmap.Save(fileName, ImageFormat.Png);
        }
    }
}
 

Jaydip

Diamond Member
Mar 29, 2010
3,691
21
81
You can start a new thread to save each individual image. That should reduce the time.

You can also save the images to a temporary buffer list and then return control to the program. Then have a thread to write each one to disk in the background. Remember this would only give the appearance of this happening quickly.It may suit your needs though.

Look at this for Asynchronous I/O

http://msdn.microsoft.com/en-us/library/kztecsys(v=vs.71).aspx
 

smakme7757

Golden Member
Nov 20, 2010
1,487
1
81
Thanks for that. I'll look into it.

The timing of the images are not important at all. When the video is finished we just look at the output for what we need. So we don't need the data right away, we just need to extract it from the video.

I'll check that out now.
 

smakme7757

Golden Member
Nov 20, 2010
1,487
1
81
Just an update, i think i have a working solution. Going on from your thoughts above this is what i came up with (Google helped me ;).

The magic more or less happens here:
Code:
        private void Test(string filename, Bitmap bitmap)
        {
            Task.Factory.StartNew(() => Savepic(filename, bitmap));
        }
I'm going to have to watch the thread count in case the software gets too overloaded, but i think this might be enough. It's a quick and nasty fix anyway.

I just ran a few runs and it seems to work. I'll have to test it some more, but it seems like your solution was what was needed :).
 
Last edited:

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
One thread per picture / plate video
You can only write as fast as the hard drive can keep up; after that it will require buffering into memory.

Once you use all the memory; you are then SOL - you can not offload to disk - that is already the bottleneck.

If you are doing this 24/7; you need to get multiple/faster storage devices.
If not, then add as much memory as needed to allow buffering until you can dump.
 

CU

Platinum Member
Aug 14, 2000
2,417
51
91
Not a C# expert, but I don't see how creating threads fixed your problem. In your original code I would think bitmap.Save() would not return until it was done writing to disk. If you were calling your Capture function to fast for the amount of data you are trying write you should see high IO wait not disk errors. Creating threads to write your data should not have fixed disk errors it would prevent your program from stalling on IO wait though. Also creating a ton of threads to write data out might make the disk IO slower as the multiple threads are trying to write to the disk at once causing the disk head to jump around. How large are the files you are writing to disk and how often do you call your Capture function? What kind of disk errors did you get?