Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.04;
Скачать: CL | DM;

Вниз

Вторичный поток, деструктор, TClientSocket   Найти похожие ветки 

 
Анонимщик ©   (2004-05-06 15:58) [0]

Будьте любезны, помогите разобраться.
Из главного окна создаю вторичный поток, который содержит TClientSocket, пытаюсь этот TClientSocket открыть (безуспешно). Через какое-то время пытаюсь уничтожить поток. Он якобы уничтожается, но, если деактивировать программу, появляется сообщение об ошибке Access violation at adress 0000. А потом программа слетает, а дебаггер говорит: "Project ... raised exception class EOSError with message "System Error. Code: 1400. Недопустимый дескриптор окна"".
С чем связано и как бороься?
Вот код:

Главное окно:

var
 SCThread: TSocketCrashThread = nil;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if SCThread <> nil then
 begin
   SCThread.Terminate;
   while not PostThreadMessage(SCThread.ThreadID, WM_USER, 0, 0) do Sleep(0);
 end else
 begin
   SCThread := TSocketCrashThread.Create("127.0.0.1", 3000);
   SCThread.Resume;
 end;  
end;

поток:

unit CrashTread;

interface

uses
 Classes, ScktComp, Windows;

type
 TSocketCrashThread = class(TThread)
 private
   { Private declarations }
   FClientSocket: TClientSocket;
 protected
   procedure Execute; override;
   procedure SocketClientError(Sender: TObject; Socket: TCustomWinSocket;
                               ErrorEvent: TErrorEvent; var ErrorCode: Integer);
 public
   constructor Create(AHost: String; APort: Integer);
   destructor Destroy; override;
 end;

implementation

{ TSocketCrashThread }

constructor TSocketCrashThread.Create(AHost: String; APort: Integer);
begin
 inherited Create(true);
 FreeOnTerminate := true;
 FClientSocket := TClientSocket.Create(nil);
 FClientSocket.Host := AHost;
 FClientSocket.Port := APort;
 FClientSocket.ClientType := ctNonBlocking;
 FClientSocket.OnError := SocketClientError;
 FClientSocket.Open;
end;

procedure TSocketCrashThread.SocketClientError(Sender: TObject; Socket: TCustomWinSocket;
                                              ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
 ErrorCode := 0;
 FClientSocket.Close;
end;

destructor TSocketCrashThread.Destroy;
begin
 FClientSocket.Free;
 inherited;
end;

procedure TSocketCrashThread.Execute;
var
 Msg: TMsg;
begin
 while GetMessage(Msg, 0, 0, 0) do
 begin
   DispatchMessage(Msg);
   if Terminated then break;
 end;
end;

end.


 
Polevi ©   (2004-05-06 16:22) [1]

clientsocket ты создаешь в основном потоке, а цикл выборки собщений - в дополнителном
смысл ?


 
Анонимщик ©   (2004-05-06 16:26) [2]

Не, clientsocket - в дополнительном потоке, в коде же написано.


 
Digitman ©   (2004-05-06 16:27) [3]


> Анонимщик ©   (06.05.04 15:58)  


создавать объект TClientSocket ты, в принципе, волен в каком угодно потоке

но вот вызов его метода Open() ты должен в том потоке, который предусматривает организацию последующего цикла выборки/диспетч-ции сообщений


 
Digitman ©   (2004-05-06 16:30) [4]


> в коде же написано


где ?!

обработчик нажатия кнопули в каком потоке вызывается ? в основном !

значит, конструктор объекта-гнезда выполняется тоже в основном .. и Open() - там же !!


 
Анонимщик ©   (2004-05-06 16:38) [5]

Так, все, спасибо. Не могу больше позорится.


 
Verg ©   (2004-05-06 16:49) [6]

Я думаю, что главное - это чтобы Поток(активизации) == Поток(освобождения). Тогда хоть AV не будет.
Ну, а в приведенном примере вообще цикл обработки сообщений в доп. потоке. нужен по-сути лишь для того, чтобы обнаружить флаг Terminated, т.к. обработкой оконных сообщений, предназначенных для FClientSocket будет заниматься главный поток, т.е. тот, который вызвал FClientSocket.Open, который в свою очередь организовал то невидимое окно, на очередь сообщений которого у будуть "сыпаться" события FClientSocket.


 
Digitman ©   (2004-05-06 16:55) [7]


> Verg ©   (06.05.04 16:49) [6]



> обработкой оконных сообщений, предназначенных для FClientSocket
> будет заниматься главный поток, т.е. тот, который вызвал
> FClientSocket.Open


прекрасно же понимаешь, что чуть ли не весь смысл доп.потока при этом теряется ...


 
Verg ©   (2004-05-06 17:08) [8]


> Digitman ©   (06.05.04 16:55) [7]


Вообще так: можешь назвать хоть одно преимущество использования сокетов в асинхронном режиме в доп. потоках?


 
Digitman ©   (2004-05-06 17:26) [9]


> Verg ©   (06.05.04 17:08) [8]


могу.
если поток выполняет не только транспортные ф-ции, а и некие иные, то почему бы нет ?


 
Polevi ©   (2004-05-06 18:30) [10]

>Verg ©   (06.05.04 17:08) [8]
просто удобно
да и в случае WSAEventSelect без доп потоков никак, из-за ограничения колва ожидаемых хендлов


 
Verg ©   (2004-05-06 20:08) [11]


> Polevi ©   (06.05.04 18:30) [10]


WSAEventSelect - это отдельный случай, я не про него говорил.

Удобно - это понятия субъективное. Я не вижу ничего удобного. Спец-окно, цикл обработки сообщений, которые посылает этому окну еще один служебный системный поток (по-моему даже не один). Какое-то нелепое построение получается. Столько промежуточных, лишних звеньев!


 
Digitman ©   (2004-05-07 08:12) [12]


> Verg ©   (06.05.04 20:08) [11]


> Спец-окно


это, м.б., и лишнее, но зато ощутимо упрощает использование асинхр.режима : просто установили ctNonBlocking, назначили обработчики -  и всех делов ..


> цикл обработки сообщений


а как без него обойтись, если кроме ожидания трансп.событий (WSAEventSelect) или трансп.сообщений спец-окну (WSAAsyncselect) поток в момент ожидания должен иметь способность немедленно реагировать на иные спецсообщения (не относящиеся непосредственно к транспорту), посылаемые ему ?

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



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.038 c
14-1087214449
Real
2004-06-14 16:00
2004.07.04
Использование программирования в жизненных задачах


4-1085349762
Malya
2004-05-24 02:02
2004.07.04
ShellExecute?


3-1086862478
quQuev
2004-06-10 14:14
2004.07.04
OLAP, Oracle, трехзвенка. Как лучше реализовать.


3-1086585953
TATIANA
2004-06-07 09:25
2004.07.04
BDE - какую базу лучше выбрать


9-1077131254
Zeqfreed
2004-02-18 22:07
2004.07.04
Посмотрите на "игру"