DynaPDF Manual - Page 651
Previous Page 650 Index Next Page 652
Function Reference
Page 651 of 839
Multi-Threading strategies
PDF pages can be very large and complex; hence, it is not always possible to render pages in just a
few milliseconds. When the rendering engine is used in a viewer application then it is usually best
to render pages in a separate thread so that the main thread becomes not blocked. A good viewer
implementation must also be able to stop rendering as fast as possible whenever necessary, e.g.
when the user requests to change the view area, zoom factor, page position or other things.
To achieve this, the rendering engine provides the function Abort() (rasAbort() in C/C++). This
function works of course only if RenderPage() is executed asynchronously. The one and only stable
and reasonable way to do this is to execute the function RenderPage() in a separate thread.
The development of a stable multi-threaded viewer requires a few design considerations to avoid
unnecessary multi-threading issues. Before we can render a PDF page we must usually import a
page or create it with DynaPDF functions.
One thing that you must consider is that it is generally not allowed to import a page in a separate
thread. However, importing a PDF page is very fast and there is generally no need to do so. Future
versions will also support specific flags to further improve the access time to external pages. So,
don't load PDF pages in a separate thread!
Notice:
DynaPDF is thread-safe but the condition is that every thread uses its own PDF instance and
anything that should be done must then be done in this thread. When we render pages in a
viewer then we must work with one instance in different threads. This tiny difference is very
important since it is a huge difference whether a library must protect all functions from
competing access or whether it must only isolate its data from one instance to another.
A viewer should only load the page from an external PDF file that should now be rendered. So,
don't call a function like ImportPDFFile() to import the entire file when it is opened. Instead, load
pages on demand as follows:
• When the user requests to open a PDF file then open it with OpenImportFile().
• Call GetInPageCount() to determine the number of pages in it.
• Create an array of pointers that holds the pointers of pages which were already loaded.
Initialize the array with NULL so that it can be used to perform a duplicate check.
• Initialize the scroll bars, zoom factor and so on, and create the image buffer so that the first
page can be displayed.
• When a page should be displayed then import it first in the main thread if necessary as
follows:
if (m_Pages[m_PageNum-1] == NULL)
{
// Important: Use EditPage() and not Append() to keep the pages
// sorted! Holes are filled with empty pages by EditPage().
pdfEditPage(m_PDF, m_PageNum);
pdfImportPageEx(m_PDF, PageNum, 1.0, 1.0);
pdfEndPage(m_PDF);
// Store the page pointer in the duplicate array
Previous topic: The update area, UpdateOnPathCount limit, UpdateOnImageCoverage limit, The return value
Next topic: How to save the image on disk?