开发者

How can I constantly take screen shots without killing performance?

开发者 https://www.devze.com 2023-04-04 18:40 出处:网络
开发者_如何学PythonThe requirement is like this: I must issue a command requesting a screenshot. The twist? The command specifies a time - and that time is in the PAST. Not forever, mind you, just wi
开发者_如何学Python

The requirement is like this:

I must issue a command requesting a screenshot. The twist? The command specifies a time - and that time is in the PAST. Not forever, mind you, just within a 30 second window.

My command indicates the actual second, and the corresponding screenshot is pulled from the rolling cache and saved in a permanent location for another process.

To accomplish this, I must take a screenshot every second, and I must preserve them for 30 seconds. After that the cache can purge itself.

My question is

What method for screenshots is least impactful against the desktop?


I can't imagine that one frame per second is going to be terrible for performance. Have you tried the simplest possible method to see if it impacts performance?

Take a look at http://www.dotnetjalps.com/2007/06/how-to-take-screenshot-in-c.html for information on how to get a screen shot.

I would suggest you use a timer:

var ssTimer = new System.Threading.Timer((s) =>
    {
      GetAndStoreScreenShot();
    }, null, 1000, 1000);

You'll need some synchronization on your cache to prevent threading problems (i.e. trying to read the first item in the cache while it's being pushed out). Probably easiest to use a lock, since that's not going to be particularly performance sensitive.

As for what to use for a cache, I'd suggest a LinkedList. It's easy to append to the list (AddLast()) and remove the first item (RemoveFirst()), and since you'll only have 30 of them and requests for screen shots will be relatively infrequent, a sequential scan to get the nth item wouldn't be too time consuming.

Or you can implement a simple circular buffer using List or Array. Increment an index to be the insertion spot, wrapping around when you increment off the end. A lookup then becomes a simple matter of modulo arithmetic.


Along the lines of what Jim said, you could store your working set of screenshots in a ConcurrentDictionary<DateTime, Bitmap>, and have two timers: The first timer would add your screenshot to the dictionary, and the second would remove anything older than 30 seconds from the dictionary.

However, this is going to be terrible for performance pretty much any way you slice it.

Something along these lines:

        var imageDictionary = new ConcurrentDictionary<DateTime, Bitmap>();

        var screenshotTaker = new System.Timers.Timer(1000);
        screenshotTaker.Elapsed += (sender, e) =>
                                       {
                                           Bitmap bmp = GetScreenshot();
                                           imageDictionary.TryAdd(DateTime.Now, bmp);
                                       };

        var screenshotRemover = new System.Timers.Timer(1000);
        screenshotRemover.Elapsed += (sender, e) =>
                                         {
                                             RemoveExpiredBitmaps();
                                         };

        screenshotTaker.Start();
        screenshotRemover.Start();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号