2

我很快就会放弃它......我有两个应用程序正在更新动态磁贴的工作后台任务。动态图块的数据被下载、解析,然后动态创建图像并用作动态图块的背景。

一两天内一切正常,但随后更新开始表现得很奇怪。前一两天,我的应用程序的两个实时磁贴每 28 分钟更新一次,就像发条一样。但随后他们开始跳过更新。当应用程序 B 不更新活动磁贴时,应用程序 A 通常会更新,因此它们不会同时更新,并且每小时仅更新一次。简而言之,它们偏离了计划。

这真的很令人沮丧,因为我需要能够依赖每 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, "Live tile", 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);
4

2 回答 2

1

如果您阅读后台代理概述 http://msdn.microsoft.com/en-us/library/hh202942(v=vs.92).aspx,您会看到它详细说明了您计划不会被遵循的几种情况. 例如:

省电模式是用户可以在设备上启用的选项,以指示应优先考虑电池寿命。如果启用此模式,即使间隔已过,定期代理也可能不会运行

于 2011-12-17T15:12:37.500 回答
0

无法保证计划任务将按预期计划运行。它甚至在执行时间安排中有一个 +/- 10 分钟的子句。

从您的问题来看,没有关于您如何记录在您期望计划运行时可能在设备上发生的其他事件/任务的信息。

因为您没有记录错误、超时或检查LastExitReason任务,所以您看到的行为可能有各种原因。

如果我不得不根据您提供的信息猜测问题出在哪里,我认为问题出在 Web 请求(网络或服务器)上,并且请求中的错误导致 UI 无法更新.

无法保证磁贴会按可预测的时间表更新。如果您必须绝对根据您的情况/要求进行更新,那么该平台将无法提供该保证。

如果您需要多个图块保持同步,我会通过让所有图块由同一进程更新来解决此问题。
这样,即使从时间角度来看,瓷砖的更新不一致,它们也会彼此同步。

于 2011-12-18T21:19:43.657 回答