Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.09.2017, 21:34   #11
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от Denis_2017 Посмотреть сообщение
Это конечно выход, но что если соединение не стабильно, пользователю по-любому нужно дождаться завершение потока?
Без вариантов. Пользователю надо дождаться завершения потоков.
Разделяйте приложение на составные части по принципу шаблону MVC: формы отдельно, потоки отдельно.
Тогда Форму можете сразу закрыть, а поток настроить на FreeOnTerminate он сам уничтожится по завершению задачи.
По поводу нестабильного соединения делайте таймаут по короче.

Цитата:
Сообщение от Denis_2017 Посмотреть сообщение
На Button1 могут нажать 685 раз
Всё равно тут критическая секция лишняя. Она же блокирует исполнение всего кода! Вы лишаете сами себя всех преимуществ параллельного исполнения. Тут по сути у вас не параллельное исполнение получается, а очередь задач. Причём не управляемая.
А раз хотим управляемую, то следует сделать очередь команд.
Возможно вам пригладятся сообщения, синхронизация потоков на сообщениях самая простая.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 07.09.2017 в 21:52.
Pavia вне форума Ответить с цитированием
Старый 07.09.2017, 21:52   #12
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

А вообще, вот что я придумал. Всю эту канитель можно сделать проще и красивее...
И юзеры могу закрывать формы в любой момент.
Код:
type
  TFmUsers = class(TForm)
    ...
    procedure EnCtr(var Msg: TMessage); message WM_USER;
    ...
  end;

procedure TFmUsers.EnCtr(var Msg: TMessage);
begin
  // Тут включаем контролы
end;

procedure TFmMain.FormCreate(Sender: TObject);
begin
  // Создаю критическую секцию
  G_GOUSERS := TCriticalSection.Create;
end;

procedure TFmMain.SP_USERS_NClick(Sender: TObject);
var FmUsers: TFmUsers;
begin
  //Создаю и запускаю поток
  with ThGOUSERS.Create(True) do
    begin
      // Создаю дочернюю форму
      Application.CreateForm(TFmUsers, FmUsers);
      FormHandle := FmUsers.Handle;  // FormHandle должен быть определён внутри ThGOUSERS
      // ....Здесь отключаем все контролы формы.... FmUsers.Button.Enabled := False...
      // Показываю дочернюю форму
      FmUsers.Show;
//      Priority := tpNormal;  // Смысл? Он и так будет Normal
      FreeOnTerminate := True;
      Resume;
    end;
end;

procedure ThGOUSERS.Execute;
begin
  try
    G_GOUSERS.enter;
    // Выполняем инициализацию и подключение к базе...
    PostMessage(FormHandle, WM_USER, 0, 0);  // включаем контролы... даже если формы уже нет, сообщение просто улетит в никуда, вновь созданные формы будет иметь другой Handle (по крайней мере, в ближайшее время)
  finally
    G_GOUSERS.leave;
  end;
end;
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru

Последний раз редактировалось 7in; 07.09.2017 в 22:00.
7in вне форума Ответить с цитированием
Старый 07.09.2017, 21:53   #13
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Всё равно тут критическая секция лишняя. Она же блокирует исполнение всего кода! Вы лишаете сами себя всех преимуществ параллельного исполнения. Тут по сути у вас не параллельное исполнение получается, а очередь задач. Причём не управляемая.
Я так понимаю, он не может делать несколько соединений с базой параллельно... а очередь и так создастся через оиждание входа в критическую секцию... Другое дело, что очередность будет не в той последовательности, в которой создавались формы, а в случайной.
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru

Последний раз редактировалось 7in; 07.09.2017 в 21:56.
7in вне форума Ответить с цитированием
Старый 07.09.2017, 22:02   #14
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Можно ещё добавить такую вещь.
В ThGOUSERS объявить Closed: Boolean, после создание потока установить её в False, а в TFmUsers создать ClosedPtr: PBoolean и далее...
Код:
procedure TFmUsers.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ClosedPtr^ := True
end;
И тогда во время подключения к базе можно проверять Closed, и если вдруг он станет True, прерывать работу и не пытаться ничего делать с базой, т.к. окно уже закрыто...
И заодно не посылать PostMessage, если Closed, т.е.:
Код:
if not Closed then PostMessage(FormHandle, WM_USER, 0, 0);
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 07.09.2017, 22:07   #15
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от 7in Посмотреть сообщение
Я так понимаю, он не может делать несколько соединений с базой параллельно... а очередь и так создастся...
Да создастся. Но лучше её создать явно, тогда вы сможете легкой ей управлять. Пользователь нажимает закрыть. Очередь задач блокируется мьютексом и из неё удаляются все запланированные задачи кроме текущей. Блокировка снимается.
Остаётся одна активная задача. Её убиваем при помощи terminate.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 07.09.2017, 22:17   #16
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от 7in Посмотреть сообщение
ClosedPtr^ := True
С точки зрения качества кода это плохо. Надо инкапсулировать такую переменную в поток и модифицировать через сообщения.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 08.09.2017, 18:13   #17
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
С точки зрения качества кода это плохо. Надо инкапсулировать такую переменную в поток и модифицировать через сообщения.
Согласен, поток может быть уже удалён при закрытии, не подумал об этом сразу.
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 08.09.2017, 18:17   #18
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Пользователь нажимает закрыть. Очередь задач блокируется мьютексом и из неё удаляются все запланированные задачи кроме текущей.
Речь пока идёт про закрытие вновь созданной формы. А что касается закрытия всей программы, то тут можно сделать так: основная программа устанавливает глобальный флаг типа MainClosed := True, а поток:
Код:
procedure ThGOUSERS.Execute;
begin
  try
    G_GOUSERS.enter;
    if not MainClosed then
    begin
      // Выполняем инициализацию и подключение к базе...
      PostMessage(FormHandle, WM_USER, 0, 0);  // включаем контролы... даже если формы уже нет, сообщение просто улетит в никуда, вновь созданные формы будет иметь другой Handle (по крайней мере, в ближайшее время)
    end;
  finally
    G_GOUSERS.leave;
  end;
end;
Хотя, я сейчас проверил, при закрытии главной формы всё потоки убиваются автоматом...
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru

Последний раз редактировалось 7in; 08.09.2017 в 18:21.
7in вне форума Ответить с цитированием
Старый 08.09.2017, 19:50   #19
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
С точки зрения качества кода это плохо. Надо инкапсулировать такую переменную в поток и модифицировать через сообщения.
Код:
procedure TFmMain.SP_USERS_NClick(Sender: TObject);
var FmUsers: TFmUsers;
begin
  //Создаю и запускаю поток
  with ThGOUSERS.Create(True) do
    begin
      // Создаю дочернюю форму
      Application.CreateForm(TFmUsers, FmUsers);
      FormHandle := FmUsers.Handle;  // FormHandle должен быть определён внутри ThGOUSERS
      FmUsers.UserThreadId := ThreadId;  // UserThreadId должен быть определён внутри TFmUsers

      // ....Здесь отключаем все контролы формы.... FmUsers.Button.Enabled := False...

      // Показываю дочернюю форму
      FmUsers.Show;
      FreeOnTerminate := True;
      Resume
    end
end;

procedure ThGOUSERS.Execute;
begin
  PeekMessage(Msg, 0, WM_USER, WM_USER, PM_REMOVE);  // Создаём очередь сообщений потока
  try
    G_GOUSERS.enter;
    if PeekMessage(Msg, 0, WM_USER, WM_USER, PM_REMOVE) then Exit;  // Это можно делать не 1 раз, а периодически
    // Выполняем инициализацию и подключение к базе...
    if not PeekMessage(Msg, 0, WM_USER, WM_USER, PM_REMOVE) then
      PostMessage(FormHandle, WM_USER, 0, 0);  // включаем контролы...
  finally
    G_GOUSERS.leave;
  end
end;
Код:
procedure TFmUsers.FormClose(Sender: TObject);
begin
  PostThreadMessage(UserThreadId, WM_USER, 0, 0)  // ThreadId - поле (переменная) формы FmUsers
end;
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Потоки, синхронизация stalker1995s Общие вопросы Delphi 6 09.01.2014 17:03
Потоки. Закрываются все потоки при ошибке в одном. Son Общие вопросы Delphi 11 01.11.2013 09:32
Потоки, синхронизация, простой denrubun Общие вопросы C/C++ 11 29.06.2013 13:37
синхронизация s.e.r.g. C++ Builder 10 11.02.2013 22:33
синхронизация perun47 Microsoft Office Excel 0 31.01.2012 22:35