实现自动保存而不中断
为了添加自动保存功能,我一直在修改 Xournal 的代码。 我最初的实现非常愚蠢:每 60 秒左右进行一次保存。 该功能表面上有效。
然而,经过一段时间的测试后,我注意到,当自动保存运行时,应用程序会暂时冻结,如果你正在笔划中间,这会很烦人。 我正在想办法解决这个问题。
我想到的一种可能性是自动保存在自动保存之前检查笔是否触摸屏幕; 如果被触摸,则附加一个仅在提笔后一秒安排的一次性回调。 (如果发生同样的事情,请重复)。 另一种可能性是充分优化保存功能,以便不存在间隙(似乎不太可能)。
有人对此有什么建议吗? Xournal 使用 Gnome/GTK 工具包,并用 C 语言编写。
更新: 我实现了防破坏逻辑,并且对最终的自动保存粒度和性能感到非常满意。 其中一次线程(幸运的是)是不必要的! 感谢大家的建议。
I have been hacking on the code for Xournal in order to add auto-save functionality. My initial implementation was very dumb: every 60 or so seconds, do a save. The feature ostensibly works.
However, after testing it out for a while, I've noticed that when auto-save runs, the application temporarily freezes up, which is quite annoying if you're in the middle of a pen stroke. I'm trying to figure out how to fix this.
One possibility I've thought up of is for autosave to check whether or not the pen is touching the screen before autosaving; if it is touched, attach a one time only callback scheduled for a second after the pen is lifted. (if the same thing happens, repeat). Another possibility would be to optimize the save function sufficiently such that there is no gap (seems unlikely).
Anyone have any suggestions about this? Xournal uses the Gnome/GTK toolkit, and is written in C.
Update: I implemented the anti-clobber logic, and I'm very happy with the resulting autosave granularity and performance. One of those times threads are (thankfully) not necessary! Thanks all for your suggestions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果 UI 在任何明显的时间段内冻结,则可能需要使用单独的线程。 如果您注意到 UI 冻结的唯一原因是您当时正在写作并且中断时间非常短暂,那么您的方法可能会起作用。 您的修复可能比创建另一个线程容易得多,因此请先尝试一下。
如果您最终使用了线程,请使用 g_threads 而不是 pthreads,因为您使用的是 GTK+。 它们会更便携。
If the UI freezes for any noticeable period of time, a separate thread is probably the way to go. If the only reason you're noticing the UI freeze is because you happen to be writing at the time and the interruption is only very brief, then your method might work. Your fix is probably way easier than creating another thread, so try that first.
If you do end up using threads, go with g_threads instead of pthreads since you're using GTK+. They'll be more portable.
虽然我同意使用线程是一个“正确”的文本框答案,但这并不总是您必须做的事情的方式。 如果您不小心,多线程往往会带来大量问题 - 这里的主要问题可能是在自动保存期间锁定对数据的访问。 然后,如果主线程进入等待访问数据的状态,您就会回到开始的地方。 因此,您创建了一个待处理更改或其他内容的队列,然后您就失去了对正在发生的事情的跟踪。 根据底层数据结构的复杂程度,制作副本也可能会冻结主线程。
无论如何重点是,我会尝试你的第一个选择。 它快速、简单、切题,而且我不明白为什么它不起作用。
(注:我还没有深入了解 Xournal,所以对此持保留态度。或者盐瓶。或者其他什么)
While I would agree using threads is a "correct" textbox answer, it's not always the way you have to do things. Multithreading tends to bring up tons of issues if you're not careful -- the main one here probably being locking access to the data during the autosave. Then if the main thread enters a wait to access the data, you're right back where you started. So then you create a queue of pending changes or something, and you lose track of what's going on. Depending on how complex the underlying data structures are, making a copy could also freeze the main thread.
Anyways point being, I would try your first option. It's quick, simple, and to the point, and I don't see why it wouldn't work.
(Note: I haven't looked under the hood of Xournal so take this with a grain of salt. Or a salt shaker. Or something)
您可以将自动保存功能推送到单独的线程吗? 通过在第二个线程上运行,您将能够与 GUI 并行运行保存,并避免冻结窗口。
我对 c 的经验很少,但我认为这个网站可以提供帮助。
Can you push the autosave functionality to a separate thread? By running on a second thread you would be able to run the save in parallel with the gui and would avoid the freezing window.
I've got very little experience with c, but I would think this site could help.
我过去也遇到过类似的情况,这是我解决它的方法(.Net):
我们看到实际发生的唯一缺陷是有人在调用事件处理程序之前杀死了应用程序并损失了 1 分钟的工作量。
I've had a similar situation in the past and here's the way I solved it (.Net):
The only flaw we've seen actually happen was someone killing the app before the event handler is called and losing 1 minute's worth of work.
这个怎么样?
使用回调的想法,但除了每 60 秒之外,还让它每 10 个输入运行一次。 对于基于时间的自动保存,存在一个问题,即丢失的内容量与用户的工作速度成正比。
如果您想更进一步,除了完整保存之外,还可以在每次更改后将部分撤消日志保存到磁盘。 这样,崩溃时可能发生的最糟糕的事情就是丢失最后一个输入笔划。
How about this?
Use the callback idea but have it run every 10 inputs in addition to every 60 seconds. With a time-based autosave, there's a problem that the amount of stuff that gets lost is proportional to how fast the user can work.
If you want to go a step further, have it save a partial undo log to disk after every change in addition to the full save. That way, the worst thing that can happen from a crash is losing the last input stroke.
我的重点是使用 hipervisor 线程通过某种哈希算法在更改事件上每 N 秒比较文件内容,然后通知父线程并回调自动保存函数。
My focus is to use an hipervisor thread comparing via some hash algorithm the file contents every N secs on change event then notify to the parent thread and callback the autosave function.