Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

### Асинхронное программирование в Datasnap: решения для бесконечных ожиданий ###

Delphi , Компоненты и Классы , Потоки

Асинхронное программирование в Datasnap: решения для бесконечных ожиданий

В современных клиент-серверных приложениях, особенно работающих с базой данных и внешними сервисами, важно уметь эффективно использовать асинхронное программирование. Это позволяет избежать задержек и "зависаний" интерфейса в ожидании выполнения длительных операций. Рассмотрим примеры, когда разработчики сталкиваются с проблемой синхронных вызовов серверных методов в приложениях Datasnap и как можно решить эти задачи, чтобы достичь бесконечного ожидания.

Проблема

Разработчик сталкивается с необходимостью реализовации асинхронных вызовов методов на сервере в приложении Datasnap, где сервер связан с базой данных SQL и использует TCP-соединение с клиентом. Клиент выполняет HTTP POST запросы к REST-сервису, и важно, чтобы основной поток не ожидал выполнения этих операций.

Решение

Шаг 1: Понимание серверного метода

Серверный модуль DM1 содержит компоненты для работы с данными и запросами к SQL-серверу, а также компоненты для выполнения REST-запросов. В DM1 есть функция PostDataAsync, которая асинхронно выполняет HTTP POST запросы к REST-сервису и возвращает количество неудачных операций через коллбэк.

Шаг 2: Реализация асинхронного вызова с коллбэком

Пример серверного метода:

procedure TServerMethods1.postCustOrderHistAsync(CustomerID: String; callback: TDBXcallback);
var
  jsonObject: TJSONObject;
  CallbackValue: TJsonValue;
  errors: Integer;
begin
  // Выполнение операций с данными
  errors := postCustOrderHist(CustomerID);
  // Формирование JSON ответа
  jsonObject := TJSONObject.Create;
  jsonObject.AddPair(TJsonPair.Create('errors', errors.ToString));
  // Вызов коллбэка
  CallbackValue := callback.Execute(jsonObject);
end;

Шаг 3: Клиентский вызов

Клиент использует функцию postCustOrderHistAsync, передавая коллбэк, который отображает статус операции после её завершения.

procedure TMainForm.BtnPostOrderHistoryClick(Sender: TObject);
var
  callback: TDBXCallback;
  ServerMethods1Client: TServerMethods1Client;
begin
  // Создание коллбэка
  callback := TDSCallbackWithMethod.Create(
    function(const Args: TJSONValue): TJSONValue
    begin
      // Обработка ответа сервера
      if Args.GetValue<Integer>('errors') = 0 then
        // Отображение уведомления об успехе
      else
        // Отображение уведомления об ошибке
      end;
      Result := TJsonTrue.Create;
    end);
  // Вызов серверного метода
  ServerMethods1Client := TServerMethods1Client.Create(DMServerConnection.SQLConnection1.DBXConnection);
  try
    ServerMethods1Client.postCustOrderHistAsync(EditCustomerId.Text, callback);
  finally
    ServerMethods1Client.Free;
  end;
end;

Шаг 4: Асинхронная отправка запросов

Проблемы, возникающие при одновременных вызовах, можно решить, разделив объекты соединения для каждого потока, чтобы избежать одновременного доступа к одному и тому же экземпляру DBXConnection.

function getNewSqlConnection(Owner: TComponent): TSQLConnection;
var
  SqlConnectionLocal: TSQLConnection;
begin
  SqlConnectionLocal := TSQLConnection.Create(nil);
  with SqlConnectionLocal do
  begin
    ConnectionString := Owner.ComponentByName('SQLConnection1').ConnectionString;
    // Настройка остальных параметров
  end;
  Result := SqlConnectionLocal;
end;

procedure TMainForm.BtnPostOrderHistoryClick(Sender: TObject);
begin
  TTask.Run(
    procedure
    var
      ServerMethods1Client: TServerMethods1Client;
      SqlConnectionLocal: TSQLConnection;
      errors: Integer;
    begin
      SqlConnectionLocal := getNewSqlConnection(Self);
      ServerMethods1Client := TServerMethods1Client.Create(SqlConnectionLocal.DBXConnection);
      try
        errors := ServerMethods1Client.postCustOrderHist(EditCustomerId.Text);
        TThread.Synchronize(nil,
          procedure
          begin
            if errors = 0 then
              showNotification(StrSentSuccessfully)
            else
              showNotification(StrSendingFailed + '(' + errors.ToString + ' not sent)')
          end);
      finally
        ServerMethods1Client.Free;
        SqlConnectionLocal.Free;
      end;
    end);
end;

Шаг 5: Использование TThread.Queue для безопасности

Для безопасной обработки коллбэков можно использовать TThread.Queue.

Вывод

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 14:17:26/0.00350022315979/0