我正在編程一個多線程的聊天服務器應用程序。因此關鍵部分是非常必要的。我只是爲線程樹視圖創建了一個包裝類。它在客戶端完美工作,但服務器引發了AV。訪問衝突在tcriticalsection.create
有兩種形式,FormServer(幾乎沒有處理,除了gui繪畫)和DataModuleServer完成所有繁重工作。
FormServer首先被創建。
實際上,線程樹視圖位於另一個包裝類TRoomTree中。
TDataModuleServer.Create
procedure TDataModuleServer.cr(Sender: TObject);
begin
Rooms := TRoomTree.Create (FormServer.tvRooms);
tvRooms:所述視覺樹狀
TRoomTree.Create
constructor TRoomTree.Create (TV : TTreeView);
begin
if Assigned (TV) then
fTreeView.Create (TV)
else
exit;
fTreeView:螺紋樹視圖;
TThreadTreeView.Create
constructor TThreadTreeView.Create (TreeView : TTreeView = nil);
begin
fLock := TCriticalSection.Create;
if Assigned (TreeView) then
fTreeView := TreeView
else
fTreeView := TTreeView.Create (nil);
end;
fTreeView:正常樹視圖;
現在TCriticalSection.Create在ntdll.dll中引發AV異常。
調用堆棧
:76cac41f KERNELBASE.RaiseException + 0x58
:0040469c NotifyNonDelphiException + $1C
:77ecb42b ; ntdll.dll
uThreadTreeView.TThreadTreeView.Create($26B4300)
uRoomTree.TRoomTree.Create($26B4300)
uServer.TDataModuleServer.cr($26A48B0)
Classes.TDataModule.DoCreate
Classes.TDataModule.AfterConstruction
[email protected]($26A48B0)
Classes.TDataModule.Create(???)
Forms.TApplication.CreateForm(???,(no value))
PlayburnServer.PlayburnServer
:773833aa kernel32.BaseThreadInitThunk + 0x12
:77ea9ef2 ntdll.RtlInitializeExceptionChain + 0x63
:77ea9ec5 ntdll.RtlInitializeExceptionChain + 0x36
任何幫助將不勝感激。
VCL組件不應該被工作線程訪問。最好將其留給主VCL線程,並使用Synchronize或VCL主線程和工作線程之間的消息。這個問題已經在SO上討論過了。 –
從構造函數中退出是有問題的 - 您還在跳過哪些其他初始化?我認爲在那裏'斷言(分配(TV))'會更好,並且我寧願讓它存在訪問衝突或引發異常而不是停止,而不是繼續構建一個半對象...不是嗎? –