powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование OLE в отдельном потоке
25 сообщений из 37, страница 1 из 2
Использование OLE в отдельном потоке
    #40119119
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте! Уже третий день бьюсь над задачей: необходимо по нажатии одной из трёх кнопок создать поток, который заблокирует кнопки, создаст ole-объект, поработает с ним и уничтожит и объект и себя, разблокировав кнопки.

Проблема заключается в том, что, либо ole-объект не хочет по какой-то причине создаваться, либо поток не завершается.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
{TMainForm}
 
  type
    TMyThread = class(TThread)
      type TThreadMethod = (tmExample, tmRead, tmCreate);
      var tm: TThreadMethod;
      var w: OLEVariant;
    private
      function CreateExample(): boolean;
    protected
      procedure Execute(); override;
      constructor Create(const tmValue: TThreadMethod);
      destructor Destroy(); override;
  end;
 
var thread: TMyThread;
 
procedure TMainForm.FormDestroy(Sender: TObject);
begin
  FreeAndNil(thread);
end;



Код: pascal
1.
2.
3.
4.
procedure TMainForm.Button3Click(Sender: TObject);
begin
  thread := TMyThread.Create(tmExample);
end;



Код: pascal
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.
{ TMyThread }
 
constructor TMyThread.Create(const tmValue: TThreadMethod);
begin
  Synchronize(MainForm.Lock);
  Self.tm := tmValue;
 
  inherited Create();
end;
 
destructor TMyThread.Destroy;
begin
  Synchronize(MainForm.UnLock);
 
  inherited;
end;
 
procedure TMyThread.Execute;
begin
  inherited;
 
  try
    if CoInitialize(nil) <> S_OK then raise Exception.Create('Ошибка при инициализации COM!');
 
    try
      w := CreateOLEObject({someobject}); // Здесь поток долго думает (секунд 20), затем выдаёт ошибку EOleSysError
 
      if tm = tmExample then
        if not CreateExample() then //working with `w`
          raise Exception.Create('Ошибка при работе с OLE!');
    except
      //some error dlgmsg
    end;
  finally
    CoUninitialize();
  end;
 
  Free;
end;



Видимо, я неправильно понимаю принцип работы потоков. Подскажите, пожалуйста, где я накосячил? Вне потока всё работает нормально.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119121
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__,
как минимум нужно Synchonize либо выкинуть, либо перенести в потоковую процедуру.
И изучить это
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119122
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блокировка компонентов не влияет, если её убрать. Ссылку уже изучал.

Что я сделал не так? За 3 дня я ничего не нашёл, потому и обратился за помощью. Ссылки-то я и сам поискать могу.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119123
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__
Код: pascal
1.
затем выдаёт ошибку EOleSysError

Как всегда, текст ошибки секретен.

Что делает Free в методе Execute?

Synchronize используется из любви к искусству или непонимания чем поток отличается от объекта TThread?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119124
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, и что мне с этим делать?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119128
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самый главный вопрос - если делать не в потоке - код работает?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119130
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cobalt747, да.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119211
Lisichkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Всё операции с VCL (кнопки) только в основном потоке, или через synchronize (что и делается в основном потоке:))
2. Работа с COM в отдельном потоке должна начинаться с CoInitialize и заканчиваться CoUninitialize
3. Укажите код ошибки, а то это гадание на кофейной гуще ;)
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119242
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__,


Уберите ключевое слово var в объявлении tm и w. Так вы сделали эти переменные глобальными, а не для экземпляра объекта.

И перенесите CoInitialize(nil) до try.

И какой смысл в try...except?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119279
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer
Уберите ключевое слово var в объявлении tm и w. Так вы сделали эти переменные глобальными, а не для экземпляра объекта.


Проверил - не глобальные. К тому же, var добавил, чтобы перекрыть type.

DmSer
И перенесите CoInitialize(nil) до try.


А разве есть разница? Он же в любом случае должен запуститься.


DmSer
И какой смысл в try...except?


Чтобы ошибки отловить и выдать сообщение, иначе как на него попасть?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119280
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Lisichkin,
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119282
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
Уберите ключевое слово var в объявлении tm и w. Так вы сделали эти переменные глобальными, а не для экземпляра объекта.
Нет. Для этого должно быть
Код: pascal
1.
class var
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119284
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, ничего не поменялось. Даже локальную переменную для функции Execute сделал без вызова CreateExample - не работает. Иногда вместо просто EOleSysError пишет "ошибка при выполнении приложения-сервера". После этого приложение не реагирует на клики. А если закрыть во время выполнения, то поток остаётся жить.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119292
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__
Иногда вместо просто EOleSysError
Так прямо и пишет? И больше ни одной буквы?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119294
Lisichkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нельзя было сразу привести код ошибки в шестнадцатеричном виде :)
Пришлось воспользоваться калькулятором :)
Ошибка при запуске многих приложений COM+: ошибка 80080005 -- выполнение сервера не удалось
Если многие приложения COM+ работают под разными учетными записями пользователей, указанными в свойстве This User, компьютер не может выделить память для создания новой кучи рабочего стола для нового пользователя. Поэтому процесс не может начаться.

https://www.google.com/search?q=ole error codes 80080005&ei=H8q0Yd-2JbCrrgS1g724DQ&ved=0ahUKEwifwqOJjtz0AhWwlYsKHbVBD9cQ4dUDCA0&uact=5&oq=ole error codes 80080005&gs_lcp=Cgdnd3Mtd2l6EAM6BwgAEEcQsANKBAhBGABKBQhAEgExSgQIRhgAUIQKWKYTYOEaaAJwAXgAgAFsiAGKBJIBAzQuMpgBAKABAcgBCMABAQ&sclient=gws-wiz
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119297
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так не поможет?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure TMyThread.Execute;
begin
  OleCheck(CoInitialize(nil));
  try
    try
      MsgWaitForMultipleObjects(0, nil, False, 0, QS_ALLEVENTS);
      w := CreateOLEObject({someobject}); // Здесь поток долго думает (секунд 20), затем выдаёт ошибку EOleSysError
 
      if tm = tmExample then
        if not CreateExample() then //working with `w`
          raise Exception.Create('Ошибка при работе с OLE!');
    except
      //some error dlgmsg
    end;
  finally
    CoUninitialize();
  end;
end;

Или даже так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure TMyThread.Execute;
begin
  OleCheck(OleInitialize(nil));
  try
    try
      w := CreateOLEObject({someobject}); // Здесь поток долго думает (секунд 20), затем выдаёт ошибку EOleSysError
 
      if tm = tmExample then
        if not CreateExample() then //working with `w`
          raise Exception.Create('Ошибка при работе с OLE!');
    except
      //some error dlgmsg
    end;
  finally
    OleUninitialize();
  end;
end;
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119299
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lisichkin
А нельзя было сразу привести код ошибки в шестнадцатеричном виде :)
Может тебе код еще текстом написать?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119301
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, ничего не изменилось, всё та же ошибка.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119305
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
__XeNoNx8000__,
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
begin
  t := TTask.Create(
    procedure
    var w: OleVariant;
    begin
      try
        OleCheck(OleInitialize(nil));
 
        w := CreateOLEObject({someobject}); // та же ошибка
        w.Visible := true;
 
        //some work with `w`
 
        //complete msg
      except
        //error msg
      end;
 
      OleUninitialize();
    end
  );
 
  t.Start();
end;
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119307
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__
Ссылку уже изучал.
И какую модель использует сервер, к которому ты обращаешься?
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119308
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Соколинский Борис, а что мне даст знание этого? Использование разных не меняет результата в любом случае. Тем более, у меня создаётся только один поток.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119309
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__,
понимание как с ним работать.
Сейчас ты это делаешь как будто он MultiThreaded, а это может быть не так.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119311
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Соколинский Борис, когда я делал в основном потоке, я даже про coinitialize не знал и без него всё работало. Как оказалось, он обязательно нужен. Но в потоке ни с ним, ни без него не работает всё равно. Даже через специальный интерфейс, как я последний код показал. Не понимаю, что не так.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119312
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__XeNoNx8000__,
если все делать методом тыка, понимание не придет.
...
Рейтинг: 0 / 0
Использование OLE в отдельном потоке
    #40119314
__XeNoNx8000__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Соколинский Борис, разве я что-то не туда натыкал? Всё сделал по документациям.
...
Рейтинг: 0 / 0
25 сообщений из 37, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование OLE в отдельном потоке
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]