Makale Özeti

Windows phone ile local bir web servisi kullanırken The remote server returned an error: NotFound. hatası ile karşılaşıyoruz.Bu hatanın sebebi şu windows phone emulatörü aslında tamamiyle ayrı bir makina gibi çalışıyor yani bizim localhost’umuz ile onun localhost’u tamamiyle farklı yani networkdeki herhangi bir makina gibi düşünebiliriz onu.Fakat direk modeme bağlı bir makina olarak değildi bizim makinamız ile onun arasında direk bağlantı yapmış gibi düşünmemiz gerekiyor.Aksi taktirde web servisimize bağlanamayabiliriz.

Makale

wp_ss_20121227_0002[1]

Bir önceki yazımda Periodic Task ve Resource Intensive Task ın özelliklerinden bahsetmiştim.Bu yazımda ise nasıl kullanıldığından bahsedicem.Task Projemizi ben kilit ekranı arka planı değiştiren projemize ekledim onun üzerinden devam ettik.Yazının sonunda projenin bitmiş halini bulabilirsiniz.

Öncelikle ilk adımda yapmamız gereken mevcut projemize bir task agent projesi ekliyoruz.schtask

Ardından yapmamız gereken bu taskı çalıştıracak olan ana projemize bu projeyi referans olarak eklemek.

referans

 

Referansımızı ekledikten sonra kod tarafına geçebiliriz.

Bir task işletim sistemi tarafından çalıştırıldığında OnInvoke metodunu çağırıyor.Bizde yapıcağımız işlemleri bu metodun içine yazıyoruz.Ek olarak bir uygulamanın bir tane task agent ı olabileceğini unutmayın.

[csharp]
 protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background
            string toastMessage = "";

            // PeriodicTask ve ResourceIntensiveTask 2 sini birden kullandığımız için
            // hangi tip task tarafından kodumuz çağırılmış onu kontrol ediyoruz.
            if (task is PeriodicTask)
            {
                // Periodic Task Çalınca çalışacak kodlar buraya
                toastMessage = "Periodic Task Çalıştı.";
            }
            else
            {
                // resource-intensive task Çalınca çalışacak kodlar buraya
                toastMessage = "Resource-intensive task çalıştı..";
            }

            // Agent çalışmaya başladığında bir toast mesajı gösterelim
            // Ana uygulamamız çalışırken bu mesaj gösterilmiyecektir
            ShellToast toast = new ShellToast();
            toast.Title = "Arka Plan Agent Örneği";
            toast.Content = toastMessage;
            toast.Show();

            // Debug yaparken 60 sn de bir çalışsın.Süreyi 60 ın katları yapınca mantıklı çalıştı fakat altında bende düzgün çalışmadı yada çalışma sistemini anlayamadım :)
#if DEBUG_AGENT
  ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60));
#endif

            // NotifyComplete ile işin bittiğini söylüyoruz.

            NotifyComplete();
        }
 
[/csharp]

Normalde uzun aralıklarda çalışan agentlarda her seferinde uzun uzun beklemek istemiyorsak debug için LaunchForTest Metodunu kullanabiliriz.Bunun çalışması için MainPage.xaml.cs in en tepesine(usinglerin de üstüne) aşağıdaki satırı ekliyoruz.Yorum satırı olarak da yazdım ben 30 sn gibi rakamlarla sağlıklı bir şekilde çalıştıramadım 60 sn yi fazla zorlamamak lazım yada daha kısa sürede çalıştırıp yöntemini yorumdan yazarsanız oldukça sevinirim.Çünkü 30-60 dk kadar farklı rakamlarla denemeler yaptım saat tutup fln :)

[csharp]
#define DEBUG_AGENT
[/csharp]

Ardından Kodumuzun MainPage sayfasına geçiyoruz.Ben arka plan uygulamamızda herhangi bir arka plan seçildiğinde hem periodic hemde resource intensive task ı çalıştırdım siz yorum haline getirerek tek tek çalışmasını sağlayabilirsiniz.2 si birliktede sorunsuz olarak çalışıyor.Kodumuza StartPeriodicAgent();StartResourceIntensiveAgent(); metodlarını ekledim.

[csharp]
   private async void ArkaPlanDegistir(Uri uri)
        {
            // Setup lock screen.
            if (!LockScreenManager.IsProvidedByCurrentApplication)
            {
                //If you're not the provider, this call will prompt the user for permission.
                //Calling RequestAccessAsync from a background agent is not allowed.
                var res = await LockScreenManager.RequestAccessAsync();

            }

            if (LockScreenManager.IsProvidedByCurrentApplication)
            {
                LockScreen.SetImageUri(uri);
                //PeriodicAgent başlat
                StartPeriodicAgent();
                //Resource Intensive Başlat
                StartResourceIntensiveAgent();
            }

        }
 
[/csharp]

Periodic Agent Başlatan Fonksitonumuz

[csharp]

    private void StartPeriodicAgent()
        {

            string periodicTaskName = "DuvarKagidiTask";
            // Eğer daha önce bu periodic task oluşturulmuşsa referansını getir
            PeriodicTask periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;

            // Eğer daha önceden varsa siliyoruz
            // Tekrar ekliyerek süresini 2 hafta daha uzatıcaz
            if (periodicTask != null)
            {
                RemoveAgent(periodicTaskName);
            }

            periodicTask = new PeriodicTask(periodicTaskName);

            // Ayarlar bölümünde arkaplan plan görevleri bölümünde görünen açıklama
            periodicTask.Description = "Task Uygulaması Sakın Engellemeyin.Açıklama metni buraya...!";

            // Try bloğu içinde ekleme yapıyoruz çünkü kullanıcı taskları disable etmiş olabilir
            try
            {
                ScheduledActionService.Add(periodicTask);
                // Debug yaparken 60 sn de bir çalışsın.Süreyi 60 ın katları yapınca mantıklı çalıştı fakat altında bende düzgün çalışmadı yada çalışma sistemini anlayamadım :)
#if DEBUG_AGENT
                ScheduledActionService.LaunchForTest(periodicTask.Name, TimeSpan.FromSeconds(60));
#endif
            }
            catch (InvalidOperationException exception)
            {
                if (exception.Message.Contains("BNS Error: The action is disabled"))
                {
                    MessageBox.Show("Bu uygulama için background agentlar kullanıcı tarafından engellenmiş.");

                }

                if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type have already been added."))
                {
                    // No user action required. The system prompts the user when the hard limit of periodic tasks has been reached.

                }

            }
            catch (SchedulerServiceException)
            {
                // No user action required.
            }
        }
 
[/csharp]

Resource Intensive Başlatan Fonsiyonumuz

[csharp]
 private void StartResourceIntensiveAgent()
        {
            ResourceIntensiveTask resourceIntensiveTask;
            string resourceIntensiveTaskName = "ResourceIntensiveAgent";
            resourceIntensiveTask = ScheduledActionService.Find(resourceIntensiveTaskName) as ResourceIntensiveTask;

            // Eğer daha önceden varsa siliyoruz
            // Tekrar ekliyerek süresini 2 hafta daha uzatıcaz
            if (resourceIntensiveTask != null)
            {
                RemoveAgent(resourceIntensiveTaskName);
            }

            resourceIntensiveTask = new ResourceIntensiveTask(resourceIntensiveTaskName);

            // Ayarlar bölümünde arkaplan plan görevleri bölümünde görünen açıklama
            resourceIntensiveTask.Description = "Resource-intensive task çalıştı.";

            // Try bloğu içinde ekleme yapıyoruz çünkü kullanıcı taskları disable etmiş olabilir
            try
            {
                ScheduledActionService.Add(resourceIntensiveTask);

                // Debug yaparken 60 sn de bir çalışsın.Süreyi 60 ın katları yapınca mantıklı çalıştı fakat altında bende düzgün çalışmadı yada çalışma sistemini anlayamadım :)
#if(DEBUG_AGENT)
                ScheduledActionService.LaunchForTest(resourceIntensiveTaskName, TimeSpan.FromSeconds(60));
#endif
            }
            catch (InvalidOperationException exception)
            {
                if (exception.Message.Contains("BNS Error: The action is disabled"))
                {
                    MessageBox.Show("Bu uygulama için background agentlar kullanıcı tarafından engellenmiş.");

                }

            }
            catch (SchedulerServiceException)
            {
                // No user action required.
            }
        }
 
[/csharp]

Eğerki bir agent mevcut ise onu kaldıran metodumuz ise RemoveAgent metodu bunu yapmamızın sebebi ise arka plan görevlerimiz 2 hafta süreyle aktif olabiliyor.Ve biz her uygulama açıldığında bu sürecin 0 lanmasını istiyoruz.

[csharp]
  private void RemoveAgent(string name)
        {
            try
            {
                ScheduledActionService.Remove(name);
            }
            catch (Exception)
            {
            }
        }
 
[/csharp]

Örnek Proje:

Internet Download Manager

TaskDemo