Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование OLE в отдельном потоке / 25 сообщений из 37, страница 1 из 2
10.12.2021, 22:05
    #40119119
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Здравствуйте! Уже третий день бьюсь над задачей: необходимо по нажатии одной из трёх кнопок создать поток, который заблокирует кнопки, создаст 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
10.12.2021, 22:18
    #40119121
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__XeNoNx8000__,
как минимум нужно Synchonize либо выкинуть, либо перенести в потоковую процедуру.
И изучить это
...
Рейтинг: 0 / 0
10.12.2021, 22:25
    #40119122
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Блокировка компонентов не влияет, если её убрать. Ссылку уже изучал.

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

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

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

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


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

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

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


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

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


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


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


Чтобы ошибки отловить и выдать сообщение, иначе как на него попасть?
...
Рейтинг: 0 / 0
11.12.2021, 18:05
    #40119280
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Lisichkin,
...
Рейтинг: 0 / 0
11.12.2021, 18:07
    #40119282
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
DmSer
Уберите ключевое слово var в объявлении tm и w. Так вы сделали эти переменные глобальными, а не для экземпляра объекта.
Нет. Для этого должно быть
Код: pascal
1.
class var
...
Рейтинг: 0 / 0
11.12.2021, 18:16
    #40119284
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
_Vasilisk_, ничего не поменялось. Даже локальную переменную для функции Execute сделал без вызова CreateExample - не работает. Иногда вместо просто EOleSysError пишет "ошибка при выполнении приложения-сервера". После этого приложение не реагирует на клики. А если закрыть во время выполнения, то поток остаётся жить.
...
Рейтинг: 0 / 0
11.12.2021, 18:55
    #40119292
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__XeNoNx8000__
Иногда вместо просто EOleSysError
Так прямо и пишет? И больше ни одной буквы?
...
Рейтинг: 0 / 0
11.12.2021, 19:01
    #40119294
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
А нельзя было сразу привести код ошибки в шестнадцатеричном виде :)
Пришлось воспользоваться калькулятором :)
Ошибка при запуске многих приложений 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
11.12.2021, 19:10
    #40119297
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Вот так не поможет?

Код: 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
11.12.2021, 19:11
    #40119299
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Lisichkin
А нельзя было сразу привести код ошибки в шестнадцатеричном виде :)
Может тебе код еще текстом написать?
...
Рейтинг: 0 / 0
11.12.2021, 19:18
    #40119301
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
_Vasilisk_, ничего не изменилось, всё та же ошибка.
...
Рейтинг: 0 / 0
11.12.2021, 20:04
    #40119305
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__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
11.12.2021, 20:10
    #40119307
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__XeNoNx8000__
Ссылку уже изучал.
И какую модель использует сервер, к которому ты обращаешься?
...
Рейтинг: 0 / 0
11.12.2021, 20:12
    #40119308
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Соколинский Борис, а что мне даст знание этого? Использование разных не меняет результата в любом случае. Тем более, у меня создаётся только один поток.
...
Рейтинг: 0 / 0
11.12.2021, 20:14
    #40119309
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__XeNoNx8000__,
понимание как с ним работать.
Сейчас ты это делаешь как будто он MultiThreaded, а это может быть не так.
...
Рейтинг: 0 / 0
11.12.2021, 20:16
    #40119311
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Соколинский Борис, когда я делал в основном потоке, я даже про coinitialize не знал и без него всё работало. Как оказалось, он обязательно нужен. Но в потоке ни с ним, ни без него не работает всё равно. Даже через специальный интерфейс, как я последний код показал. Не понимаю, что не так.
...
Рейтинг: 0 / 0
11.12.2021, 20:17
    #40119312
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
__XeNoNx8000__,
если все делать методом тыка, понимание не придет.
...
Рейтинг: 0 / 0
11.12.2021, 20:18
    #40119314
__XeNoNx8000__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование OLE в отдельном потоке
Соколинский Борис, разве я что-то не туда натыкал? Всё сделал по документациям.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование OLE в отдельном потоке / 25 сообщений из 37, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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