2

マルチスレッドのチャット サーバー アプリケーションをプログラミングしています。したがって、クリティカルセクションは非常に必要です。スレッド化されたツリー ビューのラッパー クラスを作成しました。クライアントでは完全に機能しますが、サーバーは AV を発生させます。

FormServer (GUI 描画以外はほとんど処理を行わない) と、すべての面倒な作業を行う DataModuleServer の 2 つのフォームがあります。

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
System.@AfterConstruction($26A48B0)
Classes.TDataModule.Create(???)
Forms.TApplication.CreateForm(???,(no value))
PlayburnServer.PlayburnServer
:773833aa kernel32.BaseThreadInitThunk + 0x12
:77ea9ef2 ntdll.RtlInitializeExceptionChain + 0x63
:77ea9ec5 ntdll.RtlInitializeExceptionChain + 0x36

どんな助けでも大歓迎です。

4

1 に答える 1

7

TRoomTree.Create、このコード行

fTreeView.Create(TV);

アクセス違反の責任があります。これfTreeViewは、メソッドを呼び出そうとする前に初期化されていないためです。

Delphiインスタンスは次のように作成されます。

fTreeView := TThreadTreeView.Create(TV);

スレッドモデルについてはよくわかりませんが、VCLコントロールにはGUIスレッドからのみアクセスする必要があることをご存知だと思います。

于 2012-10-26T11:08:00.793 に答える