Реферат: Обратные вызовы в MIDAS через TSocketConnection
MsgClass.MsgStr := MsgStr;
//Синхронизация - послал и забыл :-)) Выходим сразу.
//При SendMessage вызвавший клиент будет ждать, пока все остальные клиенты
//обработают сообщение, а это нежелательно
Result := PostMessage(FCallBackWnd, CM_CallbackMessage,
Longint(MsgClass),Longint(Self));
if not Result then //нуиненадо :)
MsgClass.Free;
end;
end;
Что получается: сообщение посылается в очередь каждого потока, и там сообщения накапливаются. Когда модуль данных освобождается от текущей обработки данных, а она может быть достаточно долгой, все сообщения в очереди обрабатываются и передаются на клиентскую часть в порядке поступления. Побочным эффектом является то, что клиент, вызвавший Broadcast, не ожидает окончания обработки сообщений всеми другими клиентскими частями, так как PostMessage возвращает управление немедленно. В итоге получается достаточно симпатичная система, когда один клиент посылает сообщение всем остальным и тут же продолжает работу, не ожидая окончания передачи. Остальные же клиенты получают это сообщение в момент, когда никакой обработки данных не происходит, возможно – гораздо позже. Класс TMsgClass объявлен в секции implementation следующим образом:
type TMsgClass = class(TObject) public MsgStr: WideString; end; |
и служит просто конвертом для строки сообщения, в принципе, в него можно добавить любые другие данные. Ссылка на экземпляр этого класса сохраняется только в параметре wParam сообщения, и теоретически возможна ситуация, когда сообщение будет послано модулю, который уже уничтожается (клиент отсоединился). И, естественно, сообщение обработано не будет, и не будет уничтожен экземпляр класса TMsgClass, что приведет к утечке памяти. Исходя из этого, при уничтожении класс TCallBackStub выбирает с помощью PeekMessage все оставшиеся сообщения, и уничтожает MsgClass до уничтожения окна. FCallbackWnd создается в конструкторе TCallBackStub и уничтожается в деструкторе:
constructor TCallBackStub.Create(AOwner: TrdmMain); var WindowName: string; begin inherited Create; Owner := AOwner; //создаемокносинхронизации WindowName := 'CallbackWnd' + IntToStr(InterlockedExchangeAdd(@WindowCounter,1)); FCallbackWnd := CreateWindow(CallbackWindowClass.lpszClassName, PChar(WindowName), 0, 0, 0, 0, 0, 0, 0, HInstance, nil); К-во Просмотров: 513
Бесплатно скачать Реферат: Обратные вызовы в MIDAS через TSocketConnection
|