Skip to main content

Background task in Windows 8 Metro Style App

O aplicatie nativa Metro style este diferita din unele puncte de vedere fata de o aplicatie desktop pentru Windows 7 de exemplu. Daca ati scris aplicatii pentru Windows Phone 7 va pot spune ca din unele puncte de vedere o aplicatie Metro style este mai asemanatoare cu o aplicatie Silverlight pentru Windows Phone 7.
O aplicatie in Metro style poate sa aibe doua stari. Prima stare este starea foreground, cand aplicatia este cea curenta (cea care se afiseaza pe ecran) si ruleaza ca o aplicatie normala. A doua stare este cand aceasta se afla in spate. Nu este aplicatie curenta. In momentul acesta toate firele de executie (thread-urile) sunt inghetate. Aceasta stare poarta numele de suspended. Momentul cand se face switch intre cele doua stari poate sa fie prins de catre programator. Despre cum se face acest lucru o sa vorbim cu alta ocazie.
Astazi o sa vorbim despre cum putem sa executa cod in fundal, cand aplicatia noastra este oprita. Uneori avem nevoie la aplicatie sa putem afisa updateuri pe lock screen sau sa verificam daca pe un anumit socket se intampla ceva (VOIP). Pentru acest lucru au fost creat background task.
Un lucru foarte important care trebuie stiut de la inceput despre background task este ca acesta ruleaza cand sistemul de operare doreste nu cand doreste programatorul. Exista mai multe triggere pe care le putem folosii cand vrem ca un background task sa fie apelat. Prin intermediul acestora codul nostru o sa poata sa fie executat.
Mai jos gasiti lista triggerele care sunt disponibile in acest moment:
  1. ControlChannelTrigger
  2. InternetAvailable
  3. InternetNotAvailable
  4. LockScreenApplicationAdded
  5. LockScreenApplicationRemoved
  6. MaintenanceTrigger
  7. NetworkNotificationChannelReset
  8. NetworkStateChange
  9. OnlineIdConnectedStateChange
  10. PushNotificationTrigger
  11. ServicingComplete
  12. SessionConnected
  13. SessionDisconnected
  14. SessionStart
  15. SmsReceived
  16. TimeTrigger
  17. TimeZoneChange
  18. UserAway
  19. UserPresent
Ne putem imagina ca un background task este ca o combinatie intre un Windows Service si un Windows Task. Are putin din fiecare. Un background task poate sa ruleze in doua "locatii". In functie de cum este seteaza userul aplicatia noastra:
  • Lock Screen App
  • Non-Lock Screen App
Este foarte important sa stim ca in functie de acest lucru, Windows 8 ne aluca un numar limitat de resurse pe care le putem folosii (CPU). In cazul unei aplicatii Lock Screen App, ne sunt alocate 2 secunde de CPU la un interval de 15 minute. In celalat caz ne este alocata o singura secunda la interval de 120 de minute. Atentie, 1 secunda CPU nu este tot una cu 1 secunda normala. De exemplu daca facem un request spre un URL, nu se contorizeaza timpul pana rezultatul vine de la server. La fel exista anumite limitari din punct de vedere a traficului pe care il putem face prin WiFi.
As vrea sa subliniez ca aceste valori s-ar putea sa se schimbe in viitor, din aceasta cauza este bine sa verificati de fiecare data cand un nou release sau update se face la Windows 8 (noi cel putin speram sa se schimbe putin). De exemplu un trigger de tip TimeTrigger poate sa ruleze la un interval de cel putin 15 minute. Asta inseamna ca daca avem un backgroud task care dorim sa fie rulat odata la 2 minute, nu o sa putem face acest lucru sub nici o forma.
Din punct de vedere tehnic, un background task se definieste intr-un assembly separat si trebuie inregistrat. Trebuie avut grija ca tipul de clas library selectat sa fie WinMD si nu DLL. In functe de stare pe care o are aplicatia noastra un background task poate sa fie apelat de catre:
  • aplicatia noastra - cand aplicatia ruleaza si este in foreground
  • Windows 8 - cand aplicatia este suspended sau aplicatia nu ruleaza (terminated)
Un background task poate sa aibe una sau mai multe condititi care sa fie verificare inainte sa fie rulat. De exemplu daca avem un backgroud task care are nevoie de conexiuen de internet nu dorim sa il rulam daca nu avem conexiune. In acest caz putem sa specificam o conditie care sa fie verificata inainte ca task-ul sa fie apelat.
Pentru a inregistra un task este nevoie sa ne instantiam un BackgroundTaskBuilder si sa setam triggerul si conditiile (optional) cand un background task sa ruleze. Dupa acest pas, putem sa apelam metoda Register() care o sa ne inregistreze background task-ul.
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = "FooBackgroundTask";    
builder.TaskEntryPoint = "Foo.FooBackgroundTask";   
IBackgroundTrigger trigger = new TimeTrigger(30, true);
builder.SetTrigger(trigger);
IBackgroundTaskRegistration task = builder.Register();
TaskEntryPoint specifica namespaceul si clasa unde clasa noastra este definita.
Exista doua evenimente, pe baza carora din aplicatia putem sa stim care este progresul la task si cand s-a terminat de executat. Merita de mentionat ca este nevoie sa ne inrefitram la aceste evenimente de fiecare data cand aplicatia se porneste. Cand aceasta trece din starea suspended in running nu mai este nevoie sa ne inregistram la aceste evenimente. Prin intermediul metodei BackgroundTaskRegistration.AllTasks putem sa obtinem toate task-urile inregistrate. Dupa ce obtinem task-ul pe care noi il dorim putem sa ne inregistram la evenimente.

var fooBT = BackgroundTaskRegistration.AllTasks.First(x=>x.Name == "FooBackgroundTask");
fooBT.Value.Progress += new BackgroundTaskProgressEventHandler(OnProgress);
fooBT.Value.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
Acuma ca am vazut putem sa manipulam un background task, este momentul sa vedem cum il putem definii.
Clasa noastra FooBackgroundTask, trebuie sa implementeze interfata IBackgroundTask. Aceasta are o singura metoda Run, care este apelata de catre Windows 8 cand task-ul este pornit.
public sealed class FooBackgroundTask:IBackgroundTask
   {
       private int globalcount;

       void IBackgroundTask.Run(IBackgroundTaskInstance taskInstance)
       {
               // do something
       }
   }
In interiorul metodei Run se intampla toata magia, putem sa facem orice, atata timp cat ne incadram in CPU time alocat. Prin intermediul taskInstance, care este de tip IBackgroundTaskInstance, putem sa comunicam cu aplicatia noastra care este in foreground. De exemplu putem sa trimitem notificari de tipul progress updateds.
Mai devreme am spus ca un background task poate sa faca apeluri asincrone spre orice alte resurse. Pentru a putea face acest lucru este nevoie sa folosim BackgroundTaskDeferral. Pentru fiecare operatie asincrona ar trebui sa folosim unul nou.
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
IAsyncAction action = //Call async
action.Completed = new AsyncActionCompletedHandler(  
   (IAsyncAction act, AsyncStatus stat) =>
           {
               deferral .Complete();
           });
Pentru a putea folosii un background task o aplicatie Metro style trebuie sa il declare in manifest. Fiecare background task o sa fie un alt entry point. O aplicatie poate sa aibe mai mult de un background task. Prin manifest se specifica un background task ca si o extensie la care se defineste un entry point si tipul de eveniment pentru trigger. Daca din cod se incearca inregistrarea la un alt tip de trigger, aplicatia o sa crape.
Iar mai jos puteti sa vedeti o schema care prezinta cum este lansat un background task si de catre cine.

Cam asta a fost despre background task. Inainte sa va apucati sa scrieti un background task pentru aplicatia voastra ar trebui sa va ganditi de doua ori daca aveti nevoie de unul si ar trebui sa tineti seama de urmatoarele recomandari (pe care le puteti gasii si pe MSDN):
  • Design background tasks to be short lived.
  • Design the lock screen user experience as described in the “Guidelines and checklists for lock screen tiles.”
  • Use BackgroundTaskHost.exe as the executable for background tasks.
  • Describe the background task class name or JavaScript file name accurately in the manifest.
  • Use persistent storage to share data between the background task and the app.
  • Register for progress and completion handlers in the app.
  • Register for a background task cancellation handler in the background task class.
  • Register for the ServicingComplete trigger if you expect to update the app.
  • Ensure that the background task class library is referenced in the main project and its output type is winmd.
  • Describe the triggers in the background manifest accurately.
  • Verify if the app needs to be on the lock screen.
  • Do not display UI other than toast, tiles or badges from a background task.
  • Do not rely on user interaction in background tasks.

Comments

  1. Interesant - cam aceeasi filozofie ca la WP7. Exista ceva similar cu push notification service?

    ReplyDelete
  2. Da, push notification service exista si pe Windows 8. Este foarte simular cu cel de pe WP8.
    Un demo despre push notification pe W8 poate sa fie gasit la adresa de mai jos:
    http://code.msdn.microsoft.com/windowsapps/Push-and-periodic-de225603

    ReplyDelete

Post a Comment

Popular posts from this blog

Why Database Modernization Matters for AI

  When companies transition to the cloud, they typically begin with applications and virtual machines, which is often the easier part of the process. The actual complexity arises later when databases are moved. To save time and effort, cloud adoption is more of a cloud migration in an IaaS manner, fulfilling current, but not future needs. Even organisations that are already in the cloud find that their databases, although “migrated,” are not genuinely modernised. This disparity becomes particularly evident when they begin to explore AI technologies. Understanding Modernisation Beyond Migration Database modernisation is distinct from merely relocating an outdated database to Azure. It's about making your data layer ready for future needs, like automation, real-time analytics, and AI capabilities. AI needs high throughput, which can be achieved using native DB cloud capabilities. When your database runs in a traditional setup (even hosted in the cloud), in that case, you will enc...

Cloud Myths: Migrating to the cloud is quick and easy (Pill 2 of 5 / Cloud Pills)

The idea that migration to the cloud is simple, straightforward and rapid is a wrong assumption. It’s a common misconception of business stakeholders that generates delays, budget overruns and technical dept. A migration requires laborious planning, technical expertise and a rigorous process.  Migrations, especially cloud migrations, are not one-size-fits-all journeys. One of the most critical steps is under evaluation, under budget and under consideration. The evaluation phase, where existing infrastructure, applications, database, network and the end-to-end estate are evaluated and mapped to a cloud strategy, is crucial to ensure the success of cloud migration. Additional factors such as security, compliance, and system dependencies increase the complexity of cloud migration.  A misconception regarding lift-and-shits is that they are fast and cheap. Moving applications to the cloud without changes does not provide the capability to optimise costs and performance, leading to ...

Cloud Myths: Cloud is Cheaper (Pill 1 of 5 / Cloud Pills)

Cloud Myths: Cloud is Cheaper (Pill 1 of 5 / Cloud Pills) The idea that moving to the cloud reduces the costs is a common misconception. The cloud infrastructure provides flexibility, scalability, and better CAPEX, but it does not guarantee lower costs without proper optimisation and management of the cloud services and infrastructure. Idle and unused resources, overprovisioning, oversize databases, and unnecessary data transfer can increase running costs. The regional pricing mode, multi-cloud complexity, and cost variety add extra complexity to the cost function. Cloud adoption without a cost governance strategy can result in unexpected expenses. Improper usage, combined with a pay-as-you-go model, can result in a nightmare for business stakeholders who cannot track and manage the monthly costs. Cloud-native services such as AI services, managed databases, and analytics platforms are powerful, provide out-of-the-shelve capabilities, and increase business agility and innovation. H...