Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вторичный поток, деструктор, TClientSocket


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

Будьте любезны, помогите разобраться.
Из главного окна создаю вторичный поток, который содержит 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.


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


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


> Спец-окно


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


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


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

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


Verg   (2004-05-06 20:08:00) [2]


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


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

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


Polevi   (2004-05-06 18:30:00) [3]

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


Digitman   (2004-05-06 17:26:00) [4]


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


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


Verg   (2004-05-06 17:08:00) [5]


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


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


Digitman   (2004-05-06 16:55:00) [6]


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



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


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


Verg   (2004-05-06 16:49:00) [7]

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


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

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


Digitman   (2004-05-06 16:30:00) [9]


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


где ?!

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

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


Digitman   (2004-05-06 16:27:00) [10]


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


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

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


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

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


Polevi   (2004-05-06 16:22:00) [12]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо