
A mellékelt példában a 2. évfolyam 8. számban megjelent „Remoting, avagy távoli függvényhívások megvalósítása” című cikkhez tartozó példát fogjuk most továbbfejleszteni úgy, hogy képes legyen aszinkron módon hívni a létrehozott függvényt. A mostani cikkben nem ismételjük azokat a tudnivalókat, melyet az említett cikkben már leírtunk, így az ottaniak ismerete elengedhetetlen e cikk megértéséhez.
A mellékelt példában csupán az RClient projekten kell változtatnunk, hiszen itt kell a távoli függvény hívást kezdeményeznünk. Mivel ennek módja változik most szinkronról aszinkronra, így csupán ezt a részt kell átírnunk a Form1.cs forráskódjában.
A sikeres kapcsolatfelvétel után a Button1 lenyomásakor történik a függvényhívás. Az aszinkron hívást úgy valósítjuk meg, hogy készítünk egy ún. callback függvényt, mely akkor kerül majd meghívásra, amikor a távoli függvényhívás visszatér az eredménnyel. Így alkalmazásunk rögtön értesülhet ezen eseményről. Ehhez azonban szükségünk lesz egy delegate-re, melyet úgy kell deklarálunk, hogy annak visszatérési értéke és paraméter listája megegyezik a távoli függvénnyel.
public delegate string CallbackDelegate(int a, int b);
Készítsük most el a callback függvényünket. Itt paraméterként egy IAsyncResult interfészt kapunk. Ezt felhasználva elérhetjük az általunk létrehozott CallbackDelegate-et, melynek EndInvoke függvényét meghívjuk. Ez a hívás azt eredményezi, hogy visszatérési értékként megkapjuk a távoli függvény visszatérési értékét, melyet szabadon felhasználhatunk.
public void CallbackFunction(IAsyncResult ar)
{
CallbackDelegate cd = (CallbackDelegate)((AsyncResult)ar).AsyncDelegate;
label2.Text=cd.EndInvoke(ar);
}
Nézzük hogy is történik az aszinkron hívás: szükségünk lesz AsyncCallback nevű osztály példányára, melynek konstruktorában meg kell adnunk a callback függvényünket.
private void button1_Click(object sender, System.EventArgs e)
{
AsyncCallback cb = new AsyncCallback(CallbackFunction);
Ezután létrehozatunk egy példányt a saját CallbackDelegate nevű delegate-ből. Ennek paraméterként a távoli objektumnak azt a függvényét kell megadnunk, melyet aszinkron módon szeretnénk meghívni.
CallbackDelegate cd = new CallbackDelegate(rc.AddMethod);
Végső lépésként a BeginInvoke függvénnyel elindítjuk a távoli függvény hívását. A BeginInvoke paraméter listája mindig egyezik a távoli függvény paraméter listájával, csak kiegészül két másik paraméterrel is. Így a paraméter lista első elemeiben azokat az értékeket kell megadnunk, melyeket a távoli függvénynek szeretnénk átadni, majd ezt követően megadhatjuk a már létrehozott callback függvényre való hivatkozást, hogy a távoli függvény futásának végén legyen mit meghívnia a külön szálon futó folyamatnak.
IAsyncResult ar = cd.BeginInvoke(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text), cb, null);
}
Annak szimulálására, hogy a meghívott függvény munkája időben sokáig tart, tegyünk egy üres ciklust a RObject projekt Class1.cs forráskódjában lévő AddMethod függvénybe. Hogy e ciklus meddig fusson, az az adott gép sebességétől függ, célszerű egy olyan értéket választani, hogy az AddMethod függvény futási ideje 3-4 másodpercig tartson.
public String AddMethod(int a, int b)
{
for (int i=0; i<1000000000; i++)
{
}
return a.ToString() + " + " + b.ToString() + " = " + (a+b).ToString();
}