C# 多线程 11-更多信息 03-在通用 Windows 平台应用中使用 BackgroundTask
🏷️ 《C# 多线程》
实现方式
新建 C# => Windows 通常 => 空 App 项目
打开 Package.appxmanifest 文件。在
Declarations
(声明)标签中,添加Background Tasks
(后台任务)到Supported Declarations
(支持的声明)。在
Properties
(属性中),选择System event
(系统事件)和Timer
(计时器),并将Entry point
(入口点)设置为YourNamespace.TileSchedulerTask
。YourNamespace
是你的命名空间。
示例代码
页面
xml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="50">
<TextBlock Name="Clock"
Text="HH:mm"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}"></TextBlock>
</StackPanel>
</Grid>
后台代码
csharp
/// <summary>
/// 可用于自身或导航至 Frame 内部的空白页。
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
string language = GlobalizationPreferences.Languages.First();
_cultureInfo = new CultureInfo(language);
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += (sender, e) => UpdateClockText();
}
private const string TASK_NAME_USERPRESENT = "TileSchedulerTask_UserPresent";
private const string TASK_NAME_TIMER = "TileSchedulerTask_Timer";
private readonly CultureInfo _cultureInfo;
private readonly DispatcherTimer _timer;
private void UpdateClockText()
{
Clock.Text = DateTime.Now.ToString(_cultureInfo.DateTimeFormat.FullDateTimePattern);
}
private static async void CreateClockTask()
{
BackgroundAccessStatus result = await BackgroundExecutionManager.RequestAccessAsync();
if (result == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity
|| result == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity)
{
TileSchedulerTask.CreateSchedule();
EnsureUserPresentTask();
EnsureTimerTask();
}
}
private static void EnsureTimerTask()
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == TASK_NAME_TIMER)
{
return;
}
var builder = new BackgroundTaskBuilder();
builder.Name = TASK_NAME_TIMER;
builder.TaskEntryPoint = (typeof(TileSchedulerTask)).FullName;
builder.SetTrigger(new TimeTrigger(180, false));
builder.Register();
}
}
private static void EnsureUserPresentTask()
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == TASK_NAME_USERPRESENT)
{
return;
}
var builder = new BackgroundTaskBuilder();
builder.Name = TASK_NAME_USERPRESENT;
builder.TaskEntryPoint = (typeof(TileSchedulerTask)).FullName;
builder.SetTrigger(new SystemTrigger(SystemTriggerType.UserPresent, false));
builder.Register();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_timer.Start();
UpdateClockText();
CreateClockTask();
}
}
public class TileSchedulerTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();
CreateSchedule();
deferral.Complete();
}
public static void CreateSchedule()
{
var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
var plannedUpdated = tileUpdater.GetScheduledTileNotifications();
DateTime now = DateTime.Now;
DateTime planTill = now.AddHours(4);
DateTime updateTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0).AddMinutes(1);
if (plannedUpdated.Count > 0)
{
updateTime = plannedUpdated
.Select(x => x.DeliveryTime.DateTime)
.Union(new[] { updateTime })
.Max();
}
XmlDocument documentNow = GetTilenotificationXML(now);
tileUpdater.Update(new TileNotification(documentNow)
{
ExpirationTime = now.AddMinutes(1)
});
for (var startPlanning = updateTime; startPlanning < planTill; startPlanning = startPlanning.AddMinutes(1))
{
Debug.WriteLine(startPlanning);
Debug.WriteLine(planTill);
try
{
XmlDocument document = GetTilenotificationXML(startPlanning);
var scheduleNotification = new ScheduledTileNotification(document, new DateTimeOffset(startPlanning))
{
ExpirationTime = startPlanning.AddMinutes(1)
};
tileUpdater.AddToSchedule(scheduleNotification);
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
}
}
}
private static XmlDocument GetTilenotificationXML(DateTime dateTime)
{
string language = GlobalizationPreferences.Languages.First();
var cultureInfo = new CultureInfo(language);
string shortDate = dateTime.ToString(cultureInfo.DateTimeFormat.ShortDatePattern);
string longDate = dateTime.ToString(cultureInfo.DateTimeFormat.LongDatePattern);
var document = XElement.Parse(string.Format(@"<tile>
<visual>
<binding template=""TileSquareText02"">
<text id=""1"">{0}</text>
<text id=""2"">{1}</text>
</binding>
<binding template=""TileWideText01"">
<text id=""1"">{0}</text>
<text id=""2"">{1}</text>
<text id=""3""></text>
<text id=""4""></text>
</binding>
</visual>
</tile>", shortDate, longDate));
return document.ToXmlDocument();
}
}
public static class DocumentExtensions
{
public static XmlDocument ToXmlDocument(this XElement xDocument)
{
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xDocument.ToString());
return xmlDocument;
}
}