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

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

api C++ c++builder c++빌더 code database Delphi fmx IDE ideas interbase ios migration modernization news python radstudio RAD스튜디오 tips UI UIUX vcl windows 개발 개발사례 개발팁 교육 기술레터 기술백서 데이터 데이터베이스 델파이 마이그레이션 모바일 윈도우 윈도우11 인터베이스 출시 코드 파이썬 파이어몽키 프로그래밍 프로젝트 현대화