Task-alapú párhuzamosítás Windows Phone 7 alatt

A minap arról kérték a véleményemet, hogy hogyan érdemes WP7 alatt kódot a UI-száltól függetlenül futtatni, merthogy a Threadek (szálak) használata körülményessé tud válni, az APM pedig… APM. Nem kell magyarázni. 🙂 A válasz természetesen az, hogy Taskokkal érdemes. Erre persze az volt a válasz, hogy dehát Taskok nincsenek WP7 alatt…

Ami alapvetően igaz, a Windows Phone Silverlight keretrendszere nem tartalmazza a Taskokat. De szerencsére a Microsoft ügyel arra, hogy ha nem is teljesen kulcsrakészen, de meglegyenek az újabb keretrendszerek lehetőségei a régebbiekben. (Ez itt a reklám helye.)

Tekintsük az alábbi kódot – mert ehhez nagyon hasonlót írt a kolléga:

void GetNumberAsync()
{
    Thread t = new Thread(() =>
    {
        Thread.Sleep(3000);
        var result = new Random().Next(1, 10);
        var handler = GetNumberCompleted;
        if (handler != null)
        {
            handler(this, new GetNumberEventArgs(result));
        }
    });
    t.Start();
}

event EventHandler<GetNumberEventArgs> GetNumberCompleted;

Elindít egy szálat, hogy ne a hívót terhelje. A szál vár 3 másodpercet (hogy szimuláljuk a munkát), majd egy eseményt feldobva adja vissza a bonyolult módon kikalkulált számot. Tulajdonképpen egy EAP-t látunk.

A művelet elindítását egy gombra kötjük rá, az eredményt pedig az eseményre feliratkozva jelenítjük meg a képernyőn. Valahogy így:

void Button_Click(object sender, RoutedEventArgs e)
{
    tbkStatus.Text = "Indítás...";
    GetNumberCompleted += ShowNumber;
    GetNumberAsync();
}

void ShowNumber(object sender, GetNumberEventArgs e)
{
    GetNumberCompleted -= ShowNumber;
    Dispatcher.BeginInvoke(() =>
        {
            tbkStatus.Text = "Eredmény: " + e.Result;
        });
}

Szép is, jó is, működik is. Persze már így, “kicsiben” is megjelenik a hátránya: szétszabdalja a kódot. Dispatcherezni azért kell, mert a a ShowNumber nem a UI-szálon hívódik. Megoldás? Taskok.

Ha Taskokat szeretnénk használni, hozzá kell adnunk a projekthez a dll-t, amely az ehhez szükséges infrastruktúrát tartalmazza. Ezt például letölthetjük a http://nuget.org/packages/Microsoft.Bcl/ címen. A még egyszerűbb megoldás pedig a NuGet Manager használata. A Visual Studio újabb változataival már szabadon böngészhetjük a galériába feltöltött csomagokat, és néhány kattintással hozzáadhatjuk őket a projektekhez.

A Taskokat tartalmazó dll hozzáadásának módja a következő.

1. Jobb kattintás a projekt References elemére a Solution Explorerben, majd katt a Manage NuGet Packages… pontra.

wp7tasks-1

2. A megjelenő ablakban keressünk rá (keresődoboz a jobb felső sarokban) a Microsoft BCL Portability Packre az online galériában.

wp7tasks-2

3. Kiválaszt, telepít.

Tulajdonképpen ennyi. Ezek után már átírhatjuk a korábbi kódot az alábbi formára:

Task<int> GetNumberAsync()
{
    return Task<int>.Factory.StartNew(() =>
        {
            Thread.Sleep(3000);
            return new Random().Next(1, 10);
        });
}

void Button_Click(object sender, RoutedEventArgs e)
{
    tbkStatus.Text = "Indítás...";
    GetNumberAsync().ContinueWith(t =>
        {
            Dispatcher.BeginInvoke(() =>
                tbkStatus.Text = "Eredmény: " + t.Result);
        });
}

A GetNumber nem csak elindítja a folyamatot, hanem visszaad egy objektumot, amin keresztül elérhető lesz az eredmény – innentől tehát nincs szükség az eseményre. A felhasználáskor a visszaadott Taskra a ContinueWith segítségével felfűzzük a folytatást – a szám kiírását a képernyőre. (A Thread.Sleep csak az egyszerűség kedvéért maradt ott, egyébként érdemes Task.Delayt használni.)

Bár a WP7 előreláthatólag már nem fog fejlődni, azért az ilyen kis csomagokkal mégiscsak felzárkóztathatjuk az API képességeit az újabb keretrendszerekéhez. Egyszerűbb kód, könnyebb portolás.

Reklámok

~ Szerző: Fülöp Dávid - 2013. augusztus 10..

Egy hozzászólás to “Task-alapú párhuzamosítás Windows Phone 7 alatt”

  1. […] blogolj éjjel! Rögtön miután közzétettem a tegnapi bejegyzést, leesett, hogy eredetileg nem csak a Taskokig akartam bemutatni a UI tehermentesítését, hanem […]

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s

 
%d blogger ezt kedveli: