\


 Sunday, 17 October 2004
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

  1. Vytvořte jednu assembly se serverovým objektem a nadeklarujte serverové události. Assembly umístěte pouze na serveru.
  2. 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.
  3. 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)       
Comments [8]  .Net Remoting