如何在不破坏性能的情况下不断拍摄屏幕截图?

时间:2011-09-14 23:08:08

标签: c# windows screenshot

要求是这样的:

我必须发出请求屏幕截图的命令。扭曲?该命令指定时间 - 该时间在PAST中。不要永远,请注意,在30秒的窗口内。

我的命令指示实际的秒数,相应的屏幕截图从滚动缓存中提取并保存在另一个进程的永久位置。

要做到这一点,我必须每秒拍摄一次屏幕截图,我必须保留它们30秒。之后缓存可以自行清除。

我的问题是

屏幕截图的哪种方法对桌面影响最小?

2 个答案:

答案 0 :(得分:6)

我无法想象每秒一帧会对性能造成太大影响。您是否尝试过最简单的方法来确定它是否会影响性能?

请查看http://www.dotnetjalps.com/2007/06/how-to-take-screenshot-in-c.html,了解有关如何获得屏幕截图的信息。

我建议您使用计时器:

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

您需要在缓存上进行一些同步,以防止出现线程问题(即尝试在缓存时读取缓存中的第一项)。可能最容易使用锁,因为这对性能不敏感。

至于缓存的用途,我建议使用LinkedList。可以很容易地附加到列表(AddLast())并删除第一个项目(RemoveFirst()),因为您只有30个项目并且屏幕截图请求相对不频繁,顺序扫描得到第n个项目不会太费时间。

或者您可以使用ListArray实现简单的循环缓冲区。将索引增加为插入点,在结束时递增。然后查找变成模运算的简单问题。

答案 1 :(得分:1)

根据Jim的说法,您可以将您的工作屏幕截图存储在ConcurrentDictionary<DateTime, Bitmap>中,并有两个计时器:第一个计时器会将您的屏幕截图添加到字典中,第二个计时器会删除更旧的屏幕截图字典中的30秒以上。

然而,无论你采取什么方式,这对性能来说都会很糟糕。

这些方面的东西:

        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();