Фоновая задача - пропуск расписания, иногда обновляя каждые 60 минут. - PullRequest
2 голосов
/ 17 декабря 2011

Я скоро его потеряю ... У меня есть два приложения с работающими фоновыми задачами, которые обновляют живую плитку.Данные для активной плитки загружаются, анализируются, а затем динамически создается изображение и используется в качестве фона для активной плитки.

Все работает отлично в течение дня или двух, но затем обновление начинает работатьочень странно.Первые два дня обе живые плитки для моих приложений обновляются каждые 28 минут, как по маслу.Но потом они начинают пропускать обновления.Часто приложение A обновляется, когда приложение B не обновляет активную плитку, чтобы они не обновлялись одновременно и только раз в час.Проще говоря, они далеко от графика.

Это действительно расстраивает, так как я должен иметь возможность полагаться на обновления плиток каждые 30 минут (если у меня достаточно батареи, хороший прием и так далее).

Я был бы очень признателен, если бы кто-нибудь смог мне помочь и, возможно, взглянул бы на мой код, чтобы узнать, не может ли что-то испортить интервал обновления (например, некорректный вызов NotifyComplete).Я удалил некоторый код и попытался упростить его.Пожалуйста, спросите, нужно ли вам что-то еще, чтобы понять это.

Я пытался исправить это в течение последних двух месяцев, пробовал разные телефоны и очень тщательно просматривал мой код.

Ваша помощь болееценится, чем вы когда-либо можете знать.Заранее спасибо.

My OnInvoke function:

        Timer t = null;

        ShellToast toast = new ShellToast();


        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(strUrlHBH));
            request.Accept = "*/*";
            request.AllowAutoRedirect = true;

            // disable caching.
            request.Headers["Cache-Control"] = "no-cache";
            request.Headers["Pragma"] = "no-cache";

            t = new Timer(
                state =>
                {
                    if (string.Compare(state.ToString(), id, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        //logger.Write("Timeout reached for connection [{0}], aborting download.", id);
                        runNotifyComplete = false;
                        NotifyComplete();
                        request.Abort();
                        t.Dispose();
                    }

                },
                id,
                timeout,
                0);

            request.BeginGetResponse(
                r =>
                {
                    try
                    {
                        if (t != null)
                        {
                            t.Dispose();
                        }

                        var httpRequest = (HttpWebRequest)r.AsyncState;
                        var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
                        using (var reader = new StreamReader(httpResponse.GetResponseStream()))
                        {

                            var response = reader.ReadToEnd();

                            Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                try
                                {

                                    //Parse the result

                                    if (boolResult) //If we have a result
                                    {


                                        Grid grid = new Grid();



                                        StackPanel sp = new StackPanel();
                                        sp.Height = 173;
                                        sp.Width = 173;



                                        //StreamResourceInfo info = Application.GetResourceStream(new Uri("Pin-to-start2.png", UriKind.Relative));


                                        if ((bool)settings["LiveTileMetro"] == true)
                                        {

                                            // create source bitmap for Image control (image is assumed to be alread 173x173)
                                            /*WriteableBitmap wbmp2 = new WriteableBitmap(1, 1);
                                            wbmp2.SetSource(info.Stream);
                                            Image img = new Image();
                                            img.Source = wbmp2;
                                            // add Image to Grid
                                            grid.Children.Add(img);
                                            strBackBackground = "Pin-to-start2.png";
                                        }
                                        else
                                        {*/
                                            sp.Background = (SolidColorBrush)Application.Current.Resources["PhoneAccentBrush"];
                                            //sp.Background.Opacity = 0.0;
                                            strBackBackground = "";
                                        }

                                        StreamResourceInfo info;

                                        //GC.Collect();
                                        info = Application.GetResourceStream(new Uri("/MyApp;component/images/Icons/livetile/livetile.png", UriKind.Relative));


                                        WriteableBitmap wbmp3 = new WriteableBitmap(1, 1);
                                        try
                                        {
                                            wbmp3.SetSource(info.Stream);
                                        }
                                        catch
                                        {
                                        }
                                        Image img3 = new Image();
                                        img3.Source = wbmp3;
                                        // add Image to Grid
                                        img3.Width = 173;
                                        img3.Height = 173;
                                        img3.Margin = new Thickness { Left = 0, Bottom = 0, Right = 0, Top = 0 };


                                        TextBlock txtTemperature = new TextBlock();
                                        TextBlock txtTemperatureRing = new TextBlock();

                                        txtTemperature.Foreground = new SolidColorBrush(Colors.White);
                                        txtTemperature.Text = strTemp;
                                        txtTemperature.TextAlignment = TextAlignment.Right;
                                        txtTemperatureRing.Style = (Style)Application.Current.Resources["PhoneTextTitle3Style"];
                                        txtTemperatureRing.FontFamily = new FontFamily("Segoe WP Light");
                                        txtTemperatureRing.FontSize = 40;
                                        txtTemperatureRing.Foreground = new SolidColorBrush(Colors.White);
                                        txtTemperatureRing.Text = "°";
                                        txtTemperatureRing.TextAlignment = TextAlignment.Right;

                                            txtTemperature.FontFamily = new FontFamily("Segoe WP Light");
                                            txtTemperature.FontSize = 60;
                                            txtTemperature.Margin = new Thickness { Left = 0, Bottom = 0, Right = 0, Top = -75 };
                                            txtTemperature.Height = 80;
                                            txtTemperature.Width = 145;
                                            txtTemperatureRing.Margin = new Thickness { Left = 128, Bottom = 0, Right = 0, Top = -97 };
                                            txtTemperatureRing.Height = 50;
                                            txtTemperatureRing.Width = 39;

                                        sp.Children.Add(img3);
                                        sp.Children.Add(txtTemperature);
                                        sp.Children.Add(txtTemperatureRing);


                                        //call measure, arrange and updatelayout to prepare for rendering
                                        sp.Measure(new Size(173, 173));
                                        sp.Arrange(new Rect(0, 0, 173, 173));
                                        sp.UpdateLayout();
                                        grid.Children.Add(sp);


                                        WriteableBitmap wbmp = new WriteableBitmap(173, 173);
                                        wbmp.Render(grid, null);
                                        wbmp.Invalidate();


                                        //write image to isolated storage
                                        string sIsoStorePath = @"\Shared\ShellContent\tile.png";
                                        using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
                                        {
                                            //ensure directory exists
                                            String sDirectory = System.IO.Path.GetDirectoryName(sIsoStorePath);
                                            if (!appStorage.DirectoryExists(sDirectory))
                                            {
                                                appStorage.CreateDirectory(sDirectory);
                                            }

                                            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(sIsoStorePath, System.IO.FileMode.Create, appStorage))
                                            {
                                                wbmp.SaveJpeg(stream, 173, 173, 0, 100);
                                            }
                                        }


                                        /// If application uses both PeriodicTask and ResourceIntensiveTask


                                            //ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileID=2"));
                                            ShellTile TileToFind = ShellTile.ActiveTiles.First();

                                            //test if Tile was created
                                            if (TileToFind != null)
                                            {
                                                StandardTileData NewTileData = new StandardTileData
                                                {
                                                    BackgroundImage = new Uri("isostore:Shared/ShellContent/tile.png", UriKind.Absolute),
                                                    Title = strTitle,
                                                    Count = null,
                                                    BackTitle = (string)settings["SelectedCityName"],
                                                    BackBackgroundImage = new Uri(strBackBackground, UriKind.Relative),
                                                    BackContent = strWind + Environment.NewLine + strPrecipitation
                                                };

                                                //ShellTile.Create(new Uri("/MainPage.xaml?TileID=2", UriKind.Relative), NewTileData);
                                                TileToFind.Update(NewTileData);

                                            }
                                        }



                                        if (runNotifyComplete == true)
                                        {
                                            runNotifyComplete = false;
                                            NotifyComplete();
                                        }
                                    }//If matches.count
                                }
                                catch
                                {
                                    if (runNotifyComplete == true)
                                    {
                                        runNotifyComplete = false;
                                        NotifyComplete();
                                    }
                                }
                                finally
                                {
                                    if (runNotifyComplete == true)
                                    {
                                        runNotifyComplete = false;
                                        NotifyComplete();
                                    }
                                }
                            }));
                        }



                        if (runNotifyComplete == true)
                        {
                            runNotifyComplete = false;
                            NotifyComplete();
                        }

                    }
                    catch
                    {


                        // error handling.
                        if (runNotifyComplete == true)
                        {

                            runNotifyComplete = false;
                            NotifyComplete();
                        }
                    }
                    finally
                    {
                    }
                },
                request);
        }
        catch
        {
            if (runNotifyComplete == true)
            {
                runNotifyComplete = false;
                NotifyComplete();
            }
        }
        finally
        {
        }

РЕДАКТИРОВАТЬ 1: Вот код для инициализации фоновой задачи MessageBox.Show (MyResources.LiveTileToggleMsgBoxText, «Живая плитка», MessageBoxButton.OK);

              //start background agent 
            PeriodicTask periodicTask = new PeriodicTask("AppPeriodicAgent0440");

            periodicTask.Description = "Periodic task for APP that updates the LiveTile .";
            periodicTask.ExpirationTime = System.DateTime.Now.AddDays(14);

            // If the agent is already registered with the system,
            if (ScheduledActionService.Find(periodicTask.Name) != null)
            {
                ScheduledActionService.Remove("AppPeriodicAgent0440");
            }

            try
            {
                //only can be called when application is running in foreground
                ScheduledActionService.Add(periodicTask);
            }
            catch
            {
            }

РЕДАКТИРОВАТЬ 2: Этот код запускается каждый раз, когда я выхожу из приложения, чтобы поддерживать фоновую задачу.Я положил его в OnNavigatedFrom, чтобы избежать замедления запуска приложения

//start background agent 
                        PeriodicTask periodicTask = new PeriodicTask("AppPeriodicAgent0440");

                        periodicTask.Description = "Periodic task for APP that updates the LiveTile.";
                        periodicTask.ExpirationTime = System.DateTime.Now.AddDays(14);

                        // If the agent is already registered with the system,
                        if (ScheduledActionService.Find(periodicTask.Name) != null)
                        {
                            ScheduledActionService.Remove("AppPeriodicAgent0440");
                        }

                        //only can be called when application is running in foreground
                        ScheduledActionService.Add(periodicTask);

Ответы [ 2 ]

1 голос
/ 17 декабря 2011

Если вы прочтете обзор фоновых агентов http://msdn.microsoft.com/en-us/library/hh202942(v=vs.92).aspx, вы увидите, что в нем подробно описаны несколько сценариев, в которых ваш график не будет выполняться.Например:

Режим экономии заряда батареи - это опция, которую пользователь может включить на устройстве, чтобы указать, что срок службы батареи должен быть приоритетным.Если этот режим включен, периодические агенты могут не работать, даже если истек интервал

0 голосов
/ 19 декабря 2011

Нет гарантии, что запланированное задание будет выполнено в соответствии с ожидаемым расписанием. В расписании выполнения даже есть пункт +/- 10 минут.

Из вашего вопроса нет информации о том, как вы записываете другие события / задачи, которые могут происходить на устройстве в то время, когда вы ожидаете запуска расписания.

Поскольку у вас нет регистрации ошибок, тайм-аутов или проверки LastExitReason задачи, могут быть всевозможные причины поведения, которое вы видите.

Если бы мне пришлось угадывать, где проблема, на основе предоставленной вами информации, я бы предположил, что проблема связана с веб-запросом (или сетью, или сервером), и ошибка в запросе приводит к тому, что пользовательский интерфейс не обновляется.

Невозможно гарантировать, что плитка будет обновляться по предсказуемому графику. Если вам необходимо полностью обновить это для ваших обстоятельств / требований, то эта платформа не сможет предоставить такую ​​гарантию.

Если вам нужно синхронизировать несколько плиток, я бы подошел к этому, обновив все плитки одним и тем же процессом.
Таким образом, даже если существует несоответствие в обновлении плиток с точки зрения времени, они будут синхронизированы друг с другом.

...