RAD Studio Многопоточность в Delphi на основе OmniThreadLibrary

ser4270

Местный
Регистрация
5 Май 2022
Сообщения
25
Реакции
1
Credits
86
Многопоточность в Delphi на основе OmniThreadLibrary

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

Исходники открытые - Для просмотра ссылки Войди или Зарегистрируйся
Дружественный сайт - Для просмотра ссылки Войди или Зарегистрируйся

Теперь что я заметил:
Неверная работа в параллельных потоках в случае обращения к Application.
1) нельзя создавать формы Application.CreateForm - вызывает зависание
2) нельзя использовать даже Application.MessageBox - но можно Winapi.Windows.MessageBox !!

Код:
join := Parallel.Join(
    procedure (const joinState: IOmniJoinState)
    begin
      ...
    end,
    procedure (const joinState: IOmniJoinState)
       begin
      ...
// don't use !!        Application.MessageBox('Error', 'Error', 0);
        MessageBox(0, 'Error', 'Error', 0);  // That's the only way
        ...
      end;
    end).NoWait.Execute;
 

difo

Premium
Регистрация
14 Апр 2010
Сообщения
61
Реакции
38
Credits
900
Неверная работа в параллельных потоках в случае обращения к Application.
Что и не удивительно. VCL написан так. Вся работа с компонентами vcl осуществляется ТОЛЬКО в основном потоке, а как вы это реализуете.. это уже на ваше усмотрение, например сообщения, синхронизация
 

ser4270

Местный
Регистрация
5 Май 2022
Сообщения
25
Реакции
1
Credits
86
Что и не удивительно. VCL написан так. Вся работа с компонентами vcl осуществляется ТОЛЬКО в основном потоке, а как вы это реализуете.. это уже на ваше усмотрение, например сообщения, синхронизация
Вы абсолютно правы. Но, иногда, если чего-то сделать нельзя, но очень хочется, то можно!
Вы пробовали играться с сообщениями между потоками, передачей указателей на объекты в основном потоке, созданием еще одного Application в новом потоке, передаче параметров в основной поток?
 

ser4270

Местный
Регистрация
5 Май 2022
Сообщения
25
Реакции
1
Credits
86
Проблема не столько в VCL или Application? Проблема в том как программа взаимодействует с Windows и какие API вызывает.
Например можно инициировать Application в основном потоке, а форму в параллельном (но БЕЗ CreateForm). Но вот отобразить форму нельзя. Причина - вызов API функций, например SetWindowLong и SetWindowText, ну и разумеется Perform(CM_ХХХХХ, 0, 0);

Можно наоборот, инициировать Application в параллельном, а формы создавать в основном.

С одной стороны Handle приложения у нас один. Причем не важно в каком потоке он создается. Так почему тогда после вызова функций API программа зависает? Я полагаю, что ответ приходит не в тот поток или, скорее, windows посылает ответ не туда. Это очень интересный подход, но с другой стороны, оправданный с точки зрения защиты операционки и памяти.

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

ser4270

Местный
Регистрация
5 Май 2022
Сообщения
25
Реакции
1
Credits
86

ПОНИМАНИЕ ПОТОКОВЫХ МОДЕЛЕЙ В COM ПРИ ПРОГРАММИРОВАНИИ НА DELPHI​

Для начала поясню. Всегда было принято считать, что "просто так" работать с COM-объектами в потоках нельзя. Но теперь путаницы еще больше.

Есть прекрасная статья на эту тему - Для просмотра ссылки Войди или Зарегистрируйся
или тут Для просмотра ссылки Войди или Зарегистрируйся

Для пояснения скажу, что моя программа подключается к программе 1С в параллели созданной при помощи библиотеки OTL:

Parallel.Async(procedure begin
1SConnect_App; // тут вызывается ComCon := CreateOleObject('V83.COMConnector'); и V1C_App := ComCon.Connect('Srvr="…….
end);

После создания V1C_App с ней я мог работать в основном потоке. Но не всегда.

И по все правилам вышеуказанной статьи надо использовать CoInitializeEx и CoUninitialize или OleInitialize.
Однако работало, как выяснилось, и без этого на всех рабочих станциях, кроме самого сервера. В случае работы без параллели - всё было нормально, но при использовании второго потока - V1C_App хоть и создавалась, но работать с 1С не могла.

Покопавшись в компонентах COM обратил внимание, что на сервере создан COM+, а на рабочих станциях - DCOM.
Признаюсь, я не понимаю, в чем принципиальная разница от этого для Delphi,
кто знает - объясните, как это влияет на работу или не работу в потоке.