更新2:我重新打开了这个问题,因为即使应用了我自己的问题中说明的更改,我今天仍然会收到相同的错误报告…
更新3:似乎错误发生在线程终止时,错误发生时发送的线程消息是COmniTaskMsg_Terminated.现在它很奇怪 – 我已经在我的程序中用一个线程安全的队列替换了几乎所有对Task.Comm.Send()的调用,所以我很确定线程消息的数量通过Task.Comm是一个非常小的,远远少于可能填满Windows消息队列……
我使用Delphi XE4使用OmniThreadLibrary-3.03a(刚升级到最新的svn,我会看到……),并从最终用户报告错误,错误消息和出现此问题的线程的堆栈跟踪是包括在最后.
实际上我通过用后台线程用来将日志发送到主线程的线程安全队列替换对Task.Comm.Send()的调用来减少此错误的可能性.现在我不知道在哪里看,最可能的地方在这里(但是在这个代码块中没有Task.Comm.Send()调用…):
//at this point,we are already in a thread other than the main thread. //I've two instances of the very same thread running when the program runs. myTasks := Parallel.ParallelTask.NumTasks(aTaskCount);// aTaskCount = 5 myTasks.Execute( //the following anonymous method will be executed in sub-threads and will have //multiple instances determined by the aTaskCount param. procedure (const aSubTask: IOmniTask) begin //note: this code block runs in multiple sub-threads in parallel. //aUidList can have tens of thousands (or even more) of item. while aUidList.Take(uid) and (not Self.task.CancellationToken.IsSignalled) do begin ThreadedDoSomething(); end; end );//END sub-thread
堆栈跟踪:
process id : $2f9c allocated memory : 181.30 MB largest free block : 1019.73 MB executable : MyProgram.exe exec. date/time : 2014-08-02 21:12 version : 1.0.7.256 compiled with : Delphi XE4 madExcept version : 4.0.9 callstack crc : $8b5fc164,$b1225a03,$7caf0d48 exception number : 1 exception class : EOSError exception message : System Error. Code: 1816. Not enough quota is available to process this command. thread $1160 (TOmniThread): <priority:-15> 0045c3de MyProgram.exe System.SysUtils RaiseLastOSError 0045c35b MyProgram.exe System.SysUtils RaiseLastOSError 0045c40f MyProgram.exe System.SysUtils Win32Check 0075b387 MyProgram.exe OtlContainerObserver 252 TOmniContainerWindowsMessageObserverImpl.Send 0076debb MyProgram.exe OtlTaskControl 1378 TOmniTask.InternalExecute 0076db6a MyProgram.exe OtlTaskControl 1274 TOmniTask.Execute 0077423c MyProgram.exe OtlTaskControl 3091 TOmniThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by main thread ($1408) at: 007741a1 MyProgram.exe OtlTaskControl 3080 TOmniThread.Create main thread ($1408): 0090f52d MyProgram.exe VirtualTrees 33601 TBaseVirtualTree.sortTree 00906fd1 MyProgram.exe VirtualTrees 28348 TBaseVirtualTree.EndUpdate 008f3563 MyProgram.exe VirtualTrees 17031 TBaseVirtualTree.SetRootNodeCount 00b66d99 MyProgram.exe BackupControlFrame 219 TfraBackupControl.AddLog 00b66be2 MyProgram.exe BackupControlFrame 179 TfraBackupControl.AddLog 00b69595 MyProgram.exe BackupControlFrame 844 TfraBackupControl.TimerReadLogTimer 005f430b MyProgram.exe Vcl.ExtCtrls TTimer.Timer 005f41ef MyProgram.exe Vcl.ExtCtrls TTimer.WndProc 0053fca4 MyProgram.exe System.Classes StdWndProc 76777885 USER32.dll dispatchMessageW 00656b87 MyProgram.exe Vcl.Forms TApplication.ProcessMessage 00656bca MyProgram.exe Vcl.Forms TApplication.HandleMessage 00656f05 MyProgram.exe Vcl.Forms TApplication.Run 00b83f34 MyProgram.exe MyProgram 130 initialization 75223368 kernel32.dll BaseThreadInitThunk thread $22a4: 771d0156 ntdll.dll NtWaitForMultipleObjects 75223368 kernel32.dll BaseThreadInitThunk thread $1604: 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 76780864 USER32.dll MsgWaitForMultipleObjectsEx 76780b64 USER32.dll MsgWaitForMultipleObjects 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by main thread ($1408) at: 738778e1 gdiplus.dll thread $3060 (TWorkerThread): 771cf8ca ntdll.dll NtWaitForSingleObject 76121497 KERNELBASE.dll WaitForSingleObjectEx 7522118f kernel32.dll WaitForSingleObjectEx 75221143 kernel32.dll WaitForSingleObject 008e2dbe MyProgram.exe VirtualTrees 6364 TWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by main thread ($1408) at: 008e2cda MyProgram.exe VirtualTrees 6312 TWorkerThread.Create thread $22c0: 771d1f3f ntdll.dll NtWaitForWorkViaWorkerFactory 75223368 kernel32.dll BaseThreadInitThunk thread $33d0: 771cf8ca ntdll.dll NtWaitForSingleObject 76121497 KERNELBASE.dll WaitForSingleObjectEx 7522118f kernel32.dll WaitForSingleObjectEx 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $31fc at: 7327325b rasman.dll thread $2dc4: 771cf8ca ntdll.dll NtWaitForSingleObject 764b2f7b WS2_32.dll WahReferenceContextByHandle 764b6a25 WS2_32.dll select 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by main thread ($1408) at: 75349791 WININET.dll thread $2148: 771d1f3f ntdll.dll NtWaitForWorkViaWorkerFactory 75223368 kernel32.dll BaseThreadInitThunk thread $2258 (TOmniThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 76780864 USER32.dll MsgWaitForMultipleObjectsEx 00771942 MyProgram.exe OtlTaskControl 2379 TOmniTaskExecutor.WaitForEvent 00770ddc MyProgram.exe OtlTaskControl 2148 TOmniTaskExecutor.MainMessageLoop 0076fb2e MyProgram.exe OtlTaskControl 1849 TOmniTaskExecutor.dispatchMessages 0076e7d9 MyProgram.exe OtlTaskControl 1636 TOmniTaskExecutor.Asy_Execute 0076dd59 MyProgram.exe OtlTaskControl 1354 TOmniTask.InternalExecute 0076db6a MyProgram.exe OtlTaskControl 1274 TOmniTask.Execute 0077423c MyProgram.exe OtlTaskControl 3091 TOmniThread.Execute 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $1160 (TOmniThread) at: 007741a1 MyProgram.exe OtlTaskControl 3080 TOmniThread.Create thread $618 (TOTPWorkerThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 752241d3 kernel32.dll WaitForMultipleObjects 0074b749 MyProgram.exe DSiWin32 1949 DSiWaitForTwoObjects 007782ca MyProgram.exe OtlComm 478 TOmniCommunicationEndpoint.ReceiveWait 007639cc MyProgram.exe OtlThreadPool 625 TOTPWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $2258 (TOmniThread) at: 0076348c MyProgram.exe OtlThreadPool 537 TOTPWorkerThread.Create thread $5f0 (TOTPWorkerThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 752241d3 kernel32.dll WaitForMultipleObjects 0074b749 MyProgram.exe DSiWin32 1949 DSiWaitForTwoObjects 007782ca MyProgram.exe OtlComm 478 TOmniCommunicationEndpoint.ReceiveWait 007639cc MyProgram.exe OtlThreadPool 625 TOTPWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $2258 (TOmniThread) at: 0076348c MyProgram.exe OtlThreadPool 537 TOTPWorkerThread.Create thread $2a84 (TOTPWorkerThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 752241d3 kernel32.dll WaitForMultipleObjects 0074b749 MyProgram.exe DSiWin32 1949 DSiWaitForTwoObjects 007782ca MyProgram.exe OtlComm 478 TOmniCommunicationEndpoint.ReceiveWait 007639cc MyProgram.exe OtlThreadPool 625 TOTPWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $2258 (TOmniThread) at: 0076348c MyProgram.exe OtlThreadPool 537 TOTPWorkerThread.Create thread $1ca0 (TOTPWorkerThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 752241d3 kernel32.dll WaitForMultipleObjects 0074b749 MyProgram.exe DSiWin32 1949 DSiWaitForTwoObjects 007782ca MyProgram.exe OtlComm 478 TOmniCommunicationEndpoint.ReceiveWait 007639cc MyProgram.exe OtlThreadPool 625 TOTPWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $2258 (TOmniThread) at: 0076348c MyProgram.exe OtlThreadPool 537 TOTPWorkerThread.Create thread $3248 (TOTPWorkerThread): <priority:-15> 771d0156 ntdll.dll NtWaitForMultipleObjects 761215e3 KERNELBASE.dll WaitForMultipleObjectsEx 752219f7 kernel32.dll WaitForMultipleObjectsEx 752241d3 kernel32.dll WaitForMultipleObjects 0074b749 MyProgram.exe DSiWin32 1949 DSiWaitForTwoObjects 007782ca MyProgram.exe OtlComm 478 TOmniCommunicationEndpoint.ReceiveWait 007639cc MyProgram.exe OtlThreadPool 625 TOTPWorkerThread.Execute 004ab243 MyProgram.exe madExcept HookedTThreadExecute 0053c596 MyProgram.exe System.Classes ThreadProc 0040a5b4 MyProgram.exe System 150 ThreadWrapper 004ab129 MyProgram.exe madExcept CallThreadProcSafe 004ab18e MyProgram.exe madExcept ThreadExceptFrame 75223368 kernel32.dll BaseThreadInitThunk >> created by thread $2258 (TOmniThread) at: 0076348c MyProgram.exe OtlThreadPool 537 TOTPWorkerThread.Create thread $11c8: 771d1f3f ntdll.dll NtWaitForWorkViaWorkerFactory 75223368 kernel32.dll BaseThreadInitThunk
参考this answer of another question,似乎OTL用作通信通道的Windows消息队列已满.
解决方法
procedure TOmniContainerWindowsMessageObserverImpl.Send(aMessage: cardinal; wParam,lParam: integer); begin Win32Check(PostMessage(cwmoHandle,aMessage,wParam,lParam)); end;
该异常表示具有句柄cwmoHandle的窗口的消息队列已满,并且未及时得到服务.分配给OnMessage属性时,此窗口的句柄由TOmniMessageQueue创建.很可能是进行此分配的线程被阻止(或阻塞太长时间)并且没有及时处理消息.
procedure TOmniMessageQueue.SetonMessage(const value: TOmniMessageQueueMessageEvent); begin if (not assigned(mqWinMsgObserver.OnMessage)) and assigned(value) then begin // set up observer mqWinMsgObserver.Window := DSiAllocateHWnd(WndProc); // CREATED HERE** mqWinMsgObserver.Observer := CreateContainerWindowsMessageObserver( mqWinMsgObserver.Window,MSG_CLIENT_MESSAGE,0); ContainerSubject.Attach(mqWinMsgObserver.Observer,coiNotifyOnAllInserts); mqWinMsgObserver.Observer.Activate; end else if assigned(mqWinMsgObserver.OnMessage) and (not assigned(value)) then begin // tear down observer mqWinMsgObserver.Observer.Deactivate; ContainerSubject.Detach(mqWinMsgObserver.Observer,coiNotifyOnAllInserts); FreeAndNil(mqWinMsgObserver.Observer); DSiDeallocateHWnd(mqWinMsgObserver.Window); end; mqWinMsgObserver.OnMessage := value; end;
要更具体地回答,我们需要查看更多代码,以显示实现OTL对象的位置和方式.唯一的其他线索是你的帖子就是这个;
thread $1160 (TOmniThread): <priority:-15>
这表明引发异常的线程正在以较低的优先级运行.除了您的应用程序正在积极更改线程优先级之外,这本身并不能解释任何其他内容.没有代码可以分析,没有办法说,但程序的结构可能会导致Priority Inversion问题,这使得拥有线程处理消息的能力受挫.