원격 데스크탑 애플리케이션 속도 올리기

RAD스튜디오 10.4.2에서 업데이트된 기능 중 하나는 원격 데스크톱을 통한 IDE 렌더링 속도 향상입니다. 코로나19 로 인해 원격 데스크톱으로 개발하는 개발자가 증가했다는 분석에 따라 기능이 업데이트되었습니다.

이전까지는 원격 데스크톱 연결이나 연결 해제 등 일부 상황에서 IDE가 멈추거나 깜박이는 몇 가지 AV 이슈가 있었습니다.

10.4.2에서 지원하는 QP 항목들은 다음과 같습니다:

  • 동일한 화면 설정 (동일한 머신) 으로 기존 RDP 세션 재연결 RS-99048
  • 다른 화면 설정 (예. 다른 머신) 으로 기존 RDP 세션 재연결 RS-103339
  • FMX 디자이너 열려있는 상태로 기존 RDP 세션 재연결 시 AV가 발생합니다.

추가적으로 많은 내부 리포트들이 있었습니다.

샘플 프로젝트는 공유할 수 없지만, 엠바카데로 R&D팀이 경험을 바탕으로 정리한 공유 허가를 받은 일부 내용을 오픈합니다. 다른 개발자분들에게도 유용하게 사용될 수 있었으면 합니다.

이전까지 발생했던 모든 문제의 근본적인 원인은 RDP 세션이 변경되면 (잠금, 잠금 해제, 연결, 연결 끊기) 시스템 전체 설정이 변경되어(WM_SETTINGCHANGE) IDE에서 여러 변경 사항이 발생하는 메시지 캐스케이드를 유발한다는 것이었습니다. 이는 OS에서 보낸 메시지들 간의 일부 AV가 원인이었는데, 일부 컨트롤들의 핸들 재생을 트리거하는 WM_THEMECHANGED 메시지도 여기에 포함되어 있었습니다. VCL/FMX 디자이너가 열려있는 채로 세션이 RDP를 통해 연결되면 이와 같은 문제가 발생했었습니다.

WTS API는 RDP 세션 변경 알림 (WM_WTSSESSION_CHANGE) 수신 방법을 제공합니다. 이를 관리할 수 있다면 IDE에서 세션 잠금, 잠금 해제, 연결, 연결 해제되는 시점마다 알림을 받을 수 있습니다. 그리고 WM_SETTINGCHANGE를 제어 방법을 선택하고 깜박임/리페인팅(repainting) 이슈를 방지할 수 있습니다.

R&D팀에서 전달한 내용 중 하나는 터미널 서비스에서 VCL 스타일을 사용하면 일반적인 상황에서 애플리케이션이 깜박거리는 현상이 발생할 가능성이 높다는 것이었습니다.

아래와 같은 샘플 코드(테스트되지 않음)가 애플리케이션에 유사한 지원을 추가하려는 모든 사용자들에게 올바른 포인터를 제공하는데 도움이 될 수 있었으면 좋겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
type
  TFormMain = class(TForm)
    TimerEnableMetricSettings : TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TimerEnableMetricSettingsOnTimer(Sender: TObject);
  private
    FMethodWnd: HWND;
    procedure WTS_SessionWndProc(var Message: TMessage);
    procedure DoHandleRDPLock;
    procedure DoHandleRDPUnLock;
  end;
 
var
  FormMain: TFormMain;
 
implementation
{$R *.dfm}
 
procedure TFormMain.DoHandleRDPLock;
begin
  // Prevent the VCL App reacting to WM_SETTINGCHANGE when a rdp session is locked/disconnected.
  // Stop the timer if it’s already running
  if TimerEnableMetricSettings.Enabled then
    TimerEnableMetricSettings.Enabled := False;
  Application.UpdateMetricSettings := False;
end;
 
procedure TFormMain.DoHandleRDPUnLock;
begin
  // Stop the timer if it’s already running
  if TimerEnableMetricSettings.Enabled then
    TimerEnableMetricSettings.Enabled := False;
  // Re-start the timer.
  TimerEnableMetricSettings.Enabled := True;
end;
 
procedure TFormMain.FormCreate(Sender: TObject);
begin
  TimerEnableMetricSettings.Interval := 30000;
  TimerEnableMetricSettings.Enabled := False;
  // This hooks to the method WTS_SessionWndProc below to control the Lock
  FMethodWnd := AllocateHWnd(WTS_SessionWndProc); 
  WTSRegisterSessionNotification(FMethodWnd, NOTIFY_FOR_THIS_SESSION);
end;
   
procedure TFormMain.FormDestroy(Sender: TObject);
begin
  if FMethodWnd <> 0 then
  begin
    WTSUnRegisterSessionNotification(FMethodWnd);
    DeallocateHWnd(FMethodWnd);
  end;
end;
 
procedure TFormMain.WTS_SessionWndProc(var Message: TMessage);
begin
  if Message.Msg = WM_WTSSESSION_CHANGE then
  begin
    case Message.wParam of
      WTS_SESSION_LOCK,
      WTS_REMOTE_DISCONNECT:  DoHandleRDPLock;
      WTS_REMOTE_CONNECT,
      WTS_SESSION_UNLOCK:  DoHandleRDPUnLock;
    end;
  end;
  Message.Result := DefWindowProc(FMethodWnd, Message.Msg, Message.WParam, Message.LParam);
end;
 
procedure TFormMain.TimerEnableMetricSettingsOnTimer(Sender : TObject);
begin
  // stop the timer
  TimerEnableMetricSettings.Enabled := False;
  // it is recommended to wait a few seconds before this is run
  // hence setting the timer interval to 30000 in FormCreate 
  Application.UpdateMetricSettings := True;  
end;
 
end.
cs

12.0 13 13.0 13.1 AI C++ c++빌더 chatgpt DelphiCon ios rad서버 RAD스튜디오 UI UIUX UX vcl WebStencils 개발 개발사례 기술레터 기술백서 데브옵스 데이터 데이터베이스 델파이 리눅스 마이그레이션 맥 머신러닝 모바일 새버전 샘플 세미나 안드로이드 웹 윈도우 인공지능 인터베이스 출시 커뮤니티에디션 코드 클라우드 파이썬 파이어몽키 현대화