我正在编程一个多线程的聊天服务器应用程序。因此关键部分是非常必要的。我只是为线程树视图创建了一个包装类。它在客户端完美工作,但服务器引发了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))'会更好,并且我宁愿让它存在访问冲突或引发异常而不是停止,而不是继续构建一个半对象...不是吗? –