Dotazy a odpovědi k .NET Remotingu
Tento spot přímo navazuje na starší spot o nejčastějších problémech v .NET Remotingu.
Dotazy v konferencích se často týkají událostí. Důvodem je hlavně to, že mnoho knih (namátkou třeba Building XML Web Services for Microsoft .Net platform) obsahuje “postup” pro rozchození události, který nefunguje. V čem je problém?
Když ve vzdáleném serverovém objektu nadeklarujete událost a pokusíte se k ní zaregistrovat delegáta ukazujícího na metodu na klientovi, dostanete při běhu aplikace výjimku, že se nepodařilo nahrát assembly s typem, ve kterém se nachází klientská obslužná metoda události. Server odmítne registraci delegáta u události, protože nedokáže ověřit signaturu metodu, na níž odkazuje delegát - server nemůže nalézt assembly s typem, ve kterém je deklarována metoda, protože assembly je známa a rozmístěna jen na klientovi.
Správný postup při deklaraci a používání událostí v .NET Remotingu
- Vytvořte jednu assembly se serverovým objektem a nadeklarujte serverové události. Assembly umístěte pouze na serveru.
- Vytvořte assembly, v níž bude sdílená třída s obslužnou metodou serverové události a dále bude třída obsahovat událost vlastní, která bude stejného typu jako serverová. V těle obslužné metody serverové události pouze vyvolejte událost vlastní - lokální a přepošlete argumenty obdržené ze serveru. Assembly umístěte na server i na klienta, protože klient si zaregistruje obslužnou metodu sdíleného typu k serverové události (v té chvíli již server dokáže ověřit signaturu metodu a nahrát typ, ve kterém je metoda deklarována) a současně si klient přihlásí odběr lokální události ze sdíleného typu a takto zprostředkovaně zpracuje událost ze serveru.
- Vytvořte klientskou assembly. Assembly umístěte pouze na klienta.
Dalším problémem u vzdálených událostí je korektní ošetření stavu, kdy se klient odpojí a na serveru zůstane zaregistrován delegát (například spadne spojení). Aby nedošlo k výjimce na serveru při pokusu distribuovat událost, tak jako nejjednodušší cesta se nabízí dekorování obslužné metody na klientovi atributem OneWay - atribut způsobí, že server ignoruje všechny návratové hodnoty a výjimky z metody. Velkou nevýhodou je ale hromadění delegátů ukazujících do "prázdna" a tím zvýšená režie na distribuci každé události. Lepším řešením je ruční vyvolání každého delegáta registrovaného k události a po odchycení výjimky vyřazení delegáta z další distribuce událostí.
public void OnServerEvent(EventArgs e)
{
Delegate[] delegatesList = ServerEvent.GetInvocationList();
foreach(ServerEventHandler clientDelegate in delegatesList)
{
try
{
clientDelegate(e);
}
catch
{
ServerEvent -= clientDelegate;
}
}
}
Sunday, 17 October 2004 17:33:00 (Central Europe Standard Time, UTC+01:00)
.Net Remoting