Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Вниз

Вторичный поток, деструктор, 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.06 c
14-1087270390
OFF
2004-06-15 07:33
2004.07.04
Sony DSC-V1 users guide.


3-1086727961
Almaz
2004-06-09 00:52
2004.07.04
Создание таблиц с помощью ADO


4-1085242365
NLO
2004-05-22 20:12
2004.07.04
ID


1-1087382032
Relaxxx
2004-06-16 14:33
2004.07.04
Работа с TreeView, подскажите как сделать?


3-1086786166
alex_pv
2004-06-09 17:02
2004.07.04
ClientDataSet как добраться до полученных данных???





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский