最近正在忙着开发一款三维CAD系统。BOSS希望该CAD系统具备文档自动保存功能,就像Office系列软件一样,在用户不知不觉的情况下将其所作修改进行保存,这样可以防止在意外宕机情况下用户的操作丢失。
其实添加自动保存功能并不是一件非常困难的事情,最简单的情况就是设置Timer计时器,捕捉系统消息WM_TIMER,并在Timer的响应函数里调用CDocument::OnSaveDocument()函数,使用主线程进行文档保存。不过,这样做是有弊端的。例如在我们所要做的CAD系统中,在实际使用过程中,可能会出现数据量非常庞大的零部件或组装结构。如果在这种情况下使用主线程来保存文档,文档的保存时间可能会较长。而在文档保存的过程中,系统会将光标设置为等待,因此,不仅无法再对文档进行操作,即使能操作,也会因为主线程正在忙碌状态而使系统无法响应用户操作,势必影响使用。
一个较好的方法就是使用辅助工作线程来进行文档的保存工作。由于工作线程只在后台运行,与主线程相对独立,因此,可以较好地解决用户操作与文档保存的并行问题。虽然在单核CPU情况下,所谓的多线程仍然存在CPU使用上的等待与交替过程,但由系统强制分配的CPU使用时间保证了两种操作形式上的并行,基本上解决了问题。
另外需要强调的是,由于MFC类库中的CDocument类在使用过程中,其内部函数与主线程存在线程依赖关系。具体是由一个Map影射造成的,因此如果使用传递给工作线程处理函数的CDocument类型指针直接调用CDocument::OnSaveDocument()则会造成程序断言失败而意外退出。下面是windows核心代码wincore.cpp内部包含的一个原函数。
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
注意看上述代码的注释部分。由于CDocument::OnSaveDocument()函数进行了较高层封装,与线程相关,因此,CDocument::OnSaveDocument()函数需要重写。在重写的过程中,不能再继承CDocument::OnSaveDocument()函数,而需要从更低层着手写保存操作。
关于辅助工作线程的使用方法,我会在稍后的时间里贴出程序代码和注释,敬请关注!