Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 072

/ вопрос открыт /

Здравствуйте!
у меня программа - сом сервер и клиент клиент проверяется значение переменной в бесконечном цикле и отображает её. цикл в отдельном потоке . выходит ошибка: приложение обратилось к интерфейсу относящемуся к другому потоку

SoulOfAngel Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: SoulOfAngel (статус: Посетитель)
Вопрос отправлен: 7 марта 2011, 17:52
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, SoulOfAngel!
Так как с Вашего треда происходит обращение к ActiveX компонентам, то Вы обязаны в этом треде инициализировать подсистему, отвечающую за ActiveX и Com. А в главном треде это происходит автоматически, если только используется хотя бы один компонент ActiveX. Смотрим пример тут http://chrisbensen.blogspot.com/2007/06/delphi-tips-and-tricks_26.html

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 7 марта 2011, 22:18


Мини-форум вопроса

Всего сообщений: 6; последнее сообщение — 9 марта 2011, 01:29; участников в обсуждении: 3.
Егор

Егор (статус: 10-ый класс), 7 марта 2011, 18:48 [#1]:

ошибка в 17-ой строке
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
SoulOfAngel

SoulOfAngel (статус: Посетитель), 7 марта 2011, 19:12 [#2]:

основной поток
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    ColorDialog1: TColorDialog;
    Label1: TLabel;
    Label2: TLabel;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
 //Server:Variant;
 
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
   status:boolean;
implementation
  uses unit2;
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
var  co:check;
begin
 
//Server:=CreateOLEObject('MyServer.AutoServer');
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
var  co:check;
begin
//Server:=NULL;
co.Terminate;
end;
procedure TForm1.Button1Click(Sender: TObject);
var  co:check;
begin
status:=false;
  co:=check.Create(true) ;
co.Resume;
co.Priority:=tpLower;
 
  end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
status:=true;
end;
 
end.
в основном потоке цикл работает
вот 2-й поток:
unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj, unit1, myserver_tlb, activex;
 
type
  check = class(TThread)
  private
    { Private declarations}
    Server:Variant;
  protected
    procedure Execute; override;
     procedure UpdateCaption;
     //function check.CoInitializeEx (pvReserved : pointer; coInit : longint) : HResult; stdcall;
  end;
 
implementation
 
{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,
 
      Synchronize(UpdateCaption);
 
  and UpdateCaption could look like,
 
    procedure check.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }
 
{ check }
 
procedure check.Execute;
begin
CoInitializeEx (NIL, COINIT_APARTMENTTHREADED);
  { Place thread code here }
   Server:=CreateOLEObject('MyServer.AutoServer');
     while true do
      begin
      Synchronize(UpdateCaption);
      sleep(300);
      if status=true then //CoUninitialize(nil) and
      exit;
 
      end;
 end;
  procedure check.UpdateCaption;
    begin
 
      if Server.Color=0 then
      form1.label2.caption:=('выкл') ;
      if Server.Color=1 then
      form1.label2.caption:=('вкл')  ;
      if Server.Color=2 then
      form1.label2.caption:=('на половину взведён') ;
      if terminated then exit;
    end;
end.
 <code>
SoulOfAngel

SoulOfAngel (статус: Посетитель), 7 марта 2011, 20:05 [#3]:

Вроде бы надо сделать маршлинг. Помогите пожалуйста организовать маршлингв моём коде.
SoulOfAngel

SoulOfAngel (статус: Посетитель), 7 марта 2011, 23:05 [#4]:

Здравствуйте Вадим, значит маршлинг мне не нужен?
Вадим К

Вадим К (статус: Академик), 8 марта 2011, 21:49 [#5]:

Я даже не представляю, как сюда втиснуть маршлинг.

Кстати, вот эта строка
if terminated then exit;
будучи вызванной с процедуры синхронизации потоков, может сделать совсем не то, что хочется. Я бы ее назад в execute перенес.
Присмотрелся ближе к коду, и нашел причину.
Дело в том, что когда вызывается какой то метод через Synchronize, то он отрабатывает в главном треде. А у Вас в этом методе есть обращение к полям ActiveX объекта. С учетом сказанного я бы его переписал как минимум так
unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj, unit1, myserver_tlb, activex;
 
type
  check = class(TThread)
  private
    { Private declarations}
    Server:Variant;
    mycolor:integer;// я не совсем уверен, integer ли тут.
  protected
    procedure Execute; override;
    procedure UpdateCaption;
  end;
 
implementation
 
{ check }
 
procedure check.Execute;
begin
CoInitializeEx (NIL, COINIT_APARTMENTTHREADED);
  { Place thread code here }
   Server:=CreateOLEObject('MyServer.AutoServer');
     while (not status) and (not terminated) do begin
       mycolor := Server.Color;
       Synchronize(UpdateCaption);
       sleep(300);
      end;
 end;
  procedure check.UpdateCaption;
    begin
      case mycolor of
        0: form1.label2.caption:= 'выкл';
        1: form1.label2.caption:= 'вкл';
        2: form1.label2.caption:= 'на половину взведён';
        else
          form1.label2.caption:='непонятный';
      end;
    end;
end.
Галочка "подтверждения прочтения" - вселенское зло.
SoulOfAngel

SoulOfAngel (статус: Посетитель), 9 марта 2011, 01:29 [#6]:

Спасибо вам Вадим я разобрался. Вы были правы. Если не трудно ответьте на вопрос может ли моя программа работать с другими серверами сом на пример написанными на VB?

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:35
Выполнено за 0.03 сек.