WebElektronika

Aszinkron metódushívások Callback használatával a C# nyelvben

person access_time 2017.05.29.
Megnézzük most az aszinkron metódushívást úgy, hogy Callback-et használunk.


Hozzunk létre a Visual Studio segítségével egy új konzolos projektet, a neve legyen ConsoleSzal1. Természetesen ez lesz a projekt névtere is.

A Program.cs file-ba másoljuk be a következő mintakódot, amelynek a felépítése szinte teljesen megegyezik a sorozatunk előző részében bemutatott mintaalkalmazástól, ezért a mintakód részletes ismertetéstől eltekintünk. Vegyük észre, hogy a korábban megismert mintaalkalmazásunk kiegészítésre került egy "FeldolgozasCallBack()" metódussal.

class Program
    {
        public delegate int WEdelegalt(int a, int b);

        static int szoroz(int a, int b)
        {
            Console.WriteLine("A szoroz() szál-ID : {0}", Thread.CurrentThread.ManagedThreadId);
            return a * b;
        }

        //feldolgozás szál
        static void FeldolgozasCallBack(IAsyncResult iar)
        {
            Console.WriteLine("Elindult a CallBack");
            AsyncResult eredmeny = (AsyncResult)iar;
            WEdelegalt we = (WEdelegalt)eredmeny.AsyncDelegate;
            Console.WriteLine("Eredmény : {0}", we.EndInvoke(iar));
        }
        
        static void Main(string[] args)
        {
            WEdelegalt wd = szoroz;
            Console.WriteLine("Main-ID : {0}", Thread.CurrentThread.ManagedThreadId);

            Console.WriteLine("Meghívjuk a szoroz() metódust");
            IAsyncResult iar = wd.BeginInvoke(10, 20, FeldolgozasCallBack, null);

            Console.WriteLine("Várakozunk a Main()-ben.....");

            Console.ReadLine();
        }
    }

 

Amikor az aszinkron módon meghívott szoroz() metódus véget ér, akkor nem a Main() metódusban folytatódik a vezérlés, hanem a szoroz() metódus futásának befejezése után elindul a feldolgozás szál, a FeldolgozasCallBack() metódus.
De miért indul el?

Amikor a BeginInvoke() segítségével elindítjuk aszinkron módon a szoroz() metódust, akkor a két összeszorzandó paraméter átadásán kívül átadjuk még a harmadik paraméterként annak a metódusnak a nevét is, amely a szoroz() metódus után kerüljön futtatásra. Vegyük észre, hogy a BeginInvoke() negyedik paramétere még "null".

Az első ábrán látjuk a futási eredményt, a szálak ID-jai természetesen különbözőek. Láthatjuk, hogy a Main()-ben várakozunk, miközben a szoroz() metódus meghívása (és véget érése) után fut a feldolgozási szál is (1. ábra). A szorzás eredménye a FeldolgozasCallBack()-ben kerül megjelenítésre.

kep
1. ábra   Futási eredmény
 

Módosítsuk most a mintakódot a következő példa szerint azért, hogy a BeginInvoke() negyedik paramétere is felhasználásra kerüljön.
A változtatás kiemelten került megjelenítésre.

class Program
    {
        public delegate int WEdelegalt(int a, int b);

        static int szoroz(int a, int b)
        {
            Console.WriteLine("A szoroz() szál-ID : {0}", Thread.CurrentThread.ManagedThreadId);
            return a * b;
        }

        //feldolgozás szál
        static void FeldolgozasCallBack(IAsyncResult iar)
        {
            Console.WriteLine("Elindult a CallBack");
            AsyncResult eredmeny = (AsyncResult)iar;
            WEdelegalt we = (WEdelegalt)eredmeny.AsyncDelegate;
            Console.WriteLine("Eredmény : {0}", we.EndInvoke(iar));
            Console.WriteLine("Átadott paraméter : {0}", eredmeny.AsyncState);
        }

        static void Main(string[] args)
        {
            WEdelegalt wd = szoroz;
            Console.WriteLine("Main-ID : {0}", Thread.CurrentThread.ManagedThreadId);

            Console.WriteLine("Meghívjuk a szoroz() metódust");
            IAsyncResult iar = wd.BeginInvoke(10, 20, FeldolgozasCallBack, "WebElektronika");

            Console.WriteLine("Várakozunk a Main()-ben.....");

            Console.ReadLine();
        }
    }

 

Futtassuk újra az alkalmazásunkat debug módban. Láthatjuk, hogy a BeginInvoke() meghívásakor átadott utolsó paraméter is megjelenítésre kerül a FeldolgozasCallBack() metódusban (2. ábra).

kep
2. ábra   Újabb futási eredmény