Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
DelphiНовости

Как ускорить приложения удаленного рабочего стола

remote desktop faster

Одним из обновлений функции RAD Studio 10.4.2, основанным на анализе, показывающем рост числа разработчиков, использующих удаленный рабочий стол для разработки во время Covid, стало ускорение рендеринга IDE через удаленный рабочий стол.

Основными проблемами были зависание IDE в некоторых ситуациях (например, при подключении или отключении удаленного рабочего стола), мерцание и несколько AV.

Пункты QP, рассмотренные для 10.4.2, включают:

  • Повторно подключите существующий сеанс RDP, используя те же настройки экрана (тот же компьютер) RS-99048
  • Повторно подключите существующий сеанс RDP, используя другие настройки экрана (например, с другого компьютера) RS-103339
  • Повторное подключение существующего сеанса RDP с открытым конструктором FMX вызывает AV.

Кроме того, был ряд внутренних отчетов.

Хотя у меня нет образца проекта, которым можно поделиться, у меня есть разрешение поделиться некоторыми заметками, которые команда разработчиков Embarcadero предоставила на основе своего опыта, и я надеюсь, что это будет полезно и другим разработчикам.

Основная причина всех этих проблем заключается в том, что любое изменение сеанса RDP (блокировка, разблокировка, подключение, отключение) вызывает изменение общесистемных настроек (WM_SETTINGCHANGE), вызывая каскад сообщений, который приводит к множеству перерисовок в среде IDE. Это было причиной некоторых антивирусных программ, поскольку между каскадными сообщениями, отправленными ОС, оно включало сообщение WM_THEMECHANGED, которое запускало воссоздание дескриптора для некоторых элементов управления. Это повлияло на разработчиков VCL / FMX, когда они были оставлены открытыми и сеанс был повторно подключен через RDP.

WTS API предоставляет возможность получать уведомление изменения RDP сессии (WM_WTSSESSION_CHANGE). Управление этим позволяет IDE получать уведомления, когда сеанс заблокирован, разблокирован, подключен, отключен, и отсюда мы можем выбрать, как обрабатывается WM_SETTINGCHANGE, и избежать проблем с мерцанием / перерисовкой.

Одно замечание от команды R&D заключалось в том, что использование стилей VCL в службах терминалов с большей вероятностью заставит приложение видеть мерцание при нормальных обстоятельствах.

Мы надеемся, что этот скелетный образец кода (непроверенный) предоставит указатели в правильном направлении для всех, кто хочет добавить аналогичную поддержку в свои приложения.

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.
RAD Studio 13.1 Florence Now Available See What's New in RAD Studio 13.1 Delphi is 31 - Webinar Replay

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.

Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

IN THE ARTICLES