Windows8开发-处理计划通知Toast和使用Task

来源:互联网 发布:excel数组公式怎么用 编辑:程序博客网 时间:2024/04/29 06:46

在使用计划通知时,如果过于频繁的做一些获取或删除Toast的操作,程序会抛出"无法找到元素"的异常。至于具体是什么原因,暂时搞不清楚。异常提供的信息实在有限。

不过Toast这些与UI交互并无多大关系数据,可以放到后台来处理,同时可以做一下访问频率的限制,从而减少抛出异常的几率。

使用后台线程的一大特点是,交互过程变得流畅了,而底层的一些数据可以在非UI线程中处理。可以怎么实现呢?本人是这么考虑的,首先逻辑代码放到Task.Run()中处理;同时维持一个是否正在处理Toast的标志和一个请求处理toast的列表。当有新的处理请求到达而程序块正在执行时,该请求就会被加入到请求列表中。当程序处理完一个请求之后,会从列表中查找下一个请求并执行,如果列表为空,该程序块就会退出。

下面是代码实现部分,其中Remove()函数使用了上面所说的机制。不过,此代码有一个很大的缺点,就是非线程安全的(m_IsProcessing并没有加锁):

using System.Collections.Generic;using System.Threading.Tasks;using Windows.UI.Notifications;namespace Test.NotificationService{    public class ScheduledActionService    {        #region Data Members        // 标志是否正在处理请求        private static bool m_IsProcessing = false;        // 维持toast的处理请求列表        private static List<string> m_ToastIds = new List<string>();        #endregion        #region Constructor        private ScheduledActionService()        {        }        #endregion        #region Public Methos        /// <summary>        /// 添加toast计划通知        /// </summary>        public static void Add(ScheduledToastNotification notification)        {            Task.Run(() =>                {                    ToastNotificationManager.CreateToastNotifier().AddToSchedule(notification);                });        }        /// <summary>        /// 删除toast计划通知        /// </summary>        /// /// <param name="notification">指定的toast通知</param>        public static void Remove(ScheduledToastNotification notification)        {            ToastNotificationManager.CreateToastNotifier().RemoveFromSchedule(notification);        }        /// <summary>        /// 删除toast计划通知        /// </summary>        /// <param name="toastName">指定的toast通知的名字(id)</param>        public static void Remove(string toastName)        {             Task.Run(() =>                            {                    m_ToastIds.Add(toastName);                    if (m_IsProcessing)                                              return;                    m_IsProcessing = true;                    ToastNotifier notifier = ToastNotificationManager.CreateToastNotifier();                    while (m_ToastIds.Count > 0)                    {                          IReadOnlyList<ScheduledToastNotification> toasts = notifier.GetScheduledToastNotifications();                        string toastId = m_ToastIds[0];                        m_ToastIds.RemoveAt(0);                        if (toasts.Count > 0)                        {                            foreach (var toast in toasts)                            {                                if (toast.Id == toastId)                                    notifier.RemoveFromSchedule(toast);                            }                        }                                           }                    m_IsProcessing = false;                                    }            );        }        /// <summary>        /// 获取系统已有的计划通知数列表        /// </summary>        public static IReadOnlyList<ScheduledToastNotification> GetScheduledToastNotifications()        {            return ToastNotificationManager.CreateToastNotifier().GetScheduledToastNotifications();        }        public static IReadOnlyList<ScheduledToastNotification> Find(string toastName)        {            IReadOnlyList<ScheduledToastNotification> toasts = GetScheduledToastNotifications();            List<ScheduledToastNotification> qualifiedToasts = new List<ScheduledToastNotification>();            foreach (var item in toasts)            {                if (item.Id == toastName)                    qualifiedToasts.Add(item);            }            return qualifiedToasts;        }        #endregion    }}

逻辑上应该有一些错漏的地方,欢迎指正。