要求是这样的:
我必须发出一个请求屏幕截图的命令。 扭曲? 该命令指定一个时间 – 那个时间在PAST中。 不是永远,只要在30秒的窗口内,就介意你。
我的命令指出了实际的秒数,并将相应的屏幕截图从滚动caching中提取出来,并保存在另一个进程的永久位置中。
要做到这一点,我必须每秒截图,我必须保留它们30秒。 之后,caching可以清除自己。
我的问题是
截图的哪种方法对桌面的影响最小?
我无法想象,每秒一帧的表现将会非常糟糕。 你有没有尝试过最简单的方法,看看它是否会影响性能?
看看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个项目不会太费时。
或者你可以使用List
或Array
实现一个简单的循环缓冲区。 增加一个索引作为插入点,当你递增时结束。 查找然后成为模算术的一个简单的问题。
按照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();