2

onExcecuteイベント内で(TidNotifyを使用して)操作するデータベースを使用するTidTCPServerがあります。アプリケーションを閉じる可能性はなく、すべてが非常にうまく機能します。アプリケーションを閉じている間、すべての通知インスタンスが作業を終了したかどうかわからず、通常はランタイム エラー 216 が発生します (「通知」作業が終了する前にデータベースを閉じると思います)。確認する方法はありますか - 古い通知の投稿を待っているか、アプリケーションを閉じることができるかどうかを確認できません。他の質問は、サーバープロセスの終了中に TidTCPServer が新しい接続を受け入れないように保護する方法です。以下のようなコードを使用していますが、それでもエラーが発生します。

type
  TShutdownThread = class(TThread)
  protected
    procedure Execute; override;
  end;


procedure TShutdownThread.Execute;
begin
  IdTCPServer.Active := false;
end;


//closing...
  if IdTCPServer.Active then
  begin
    with TShutdownThread.Create(false) do
      try
        WaitFor; // internally processes sync requests...
      finally
        Free;
      end;
  end;
4

1 に答える 1

3

確認する方法はありますか - 古い通知の投稿を待っているか、アプリケーションを閉じることができるかどうかを確認できません。

TIdNotifyは非同期であるため、後で実行するためにメイン スレッドのメッセージ キューにリクエストを送信します。が終了した後も、保留中のリクエストがキューに残っている可能性がありますTShutdownThread.WaitFor()。RTL のCheckSynchronize()関数を呼び出して残りのリクエストを処理できます。

if IdTCPServer.Active then
begin
  with TShutdownThread.Create(false) do
  try
    WaitFor;
  finally
    Free;
  end;
  CheckSynchronize;
end;

サーバープロセスの終了中にTidTCPServerが新しい接続を受け入れないように保護する方法。

が非アクティブ化されている間TIdTCPServer、リスニング ポートを閉じます。ただし、サーバーがポートを閉じる前に、新しいクライアントを受け入れる機会が非常にわずかにあります。サーバーはシャットダウンの一部としてこれらの接続を閉じますが、これらの接続に対してイベントを呼び出したくない場合はOnExecute、サーバーを非アクティブ化する前にコードのどこかにフラグを設定してから、OnConnectイベントでそのフラグを確認してください。設定されている場合は、すぐにクライアントを切断します。例:

var
  ShuttingDown: boolean = False;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
  if ShuttingDown then
  begin
    AContext.Connection.Disconnect;
    Exit;
  end;
  ...
end;

...

if IdTCPServer.Active then
begin
  ShuttingDown := True;
  try
    with TShutdownThread.Create(false) do
    try
      WaitFor;
    finally
      Free;
    end;
    CheckSynchronize;
  finally
    ShuttingDown := False;
  end;
end;
于 2013-02-17T22:16:40.417 に答える