Реферат: Обратные вызовы в 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