我的C#应用程序存在瓶颈,我需要将页面从PDF或Tiff文件加载为位图,并在内存中处理此位图。 Tiff文件加载速度相当快,以及第一方PDF(我们可以自己阅读)。当PDF文件是第三方并且我们需要解析PDF页面并将其转换为位图时,瓶颈就会出现。这是昂贵的,比第一方PDF慢500倍,以获得一个想法。其中一些PDF文件非常大,因此我们首先避免将整个文档加载到内存中。
在页面上完成的工作是在一个单独的过程中完成的(神奇地),而我的应用程序等待它完成。正因为如此,我相信如果我加载一个小缓冲区(一次说5页)异步它将加速这些第三方PDF文件的执行。
IntPtr[] dibbuffer = new IntPtr[5];
dibbuffer[0] = LoadPage(0); //pre-emptive first page
BeginAsyncFillBuffer(dibbuffer);
for (i=0; i<NUM_PAGES; ++i)
{
IntenseProcessing(dibbuffer[current_page_index_in_buffer]);
}
EndAsyncFillBuffer();
答案 0 :(得分:0)
这就是我最终的结果。我希望不是每X毫秒轮询它更“懒惰”,只在需要时填充单独线程上的缓冲区。如果有人可以改进这一点,请做。
class MyGhettoBuffer
{
Target _target = null; //contains info on the file @ hand
Queue _q = null;
Queue _synchQ = null;
Thread _loop = null;
ManualResetEvent _throttle = new ManualResetEvent(false);
int _curpage = 0;
private MyGhettoBuffer() { }
public MyGhettoBuffer(Target target)
{
_target = target;
_q = new Queue();
_synchQ = Queue.Synchronized(_q);
_loop = new Thread(MainLoop);
_loop.Start();
}
public bool HasPagesLeft //determine when to stop processing queue
{
get
{
if (_curpage >= _target.NumPages &&
_synchQ.Count == 0)
return false;
else
return true;
}
}
//if the buffer hasnt caught up load the page on the processing thread
public IntPtr GetNextPage()
{
lock (this)
{
if (_synchQ.Count == 0)
{
IntPtr dib =
LoadDib(_target.FullPath, _curpage);
_curpage++;
return dib;
}
else
{
object o = _synchQ.Dequeue();
if (o is IntPtr)
{
return (IntPtr)o;
}
else
{
throw new InvalidCastException("Object in page queue is not an IntPtr");
}
}
}
}
private void MainLoop()
{
while (true)
{
if (_curpage < _target.NumPages)
{
if (_synchQ.Count < 5)
{
lock (this)
{
IntPtr dib =
LoadDib(_target.FullPath, _curpage);
_synchQ.Enqueue(dib);
_curpage++;
}
}
}
else
{
return;
}
_throttle.WaitOne(100, false); //dont use a %@#! ton of cpu cycles
}
}
}
然后,在我的处理线程中,我做了类似的事情:
MyGhettoBuffer buffer = new MyGhettoBuffer(target);
while (buffer.HasPagesLeft)
{
IntPtr dib = GetNextPage();
//Process the dib here
FreeDib(dib);
}