Repository navigation
Expand file tree
/
Copy pathBroadcastScheduler.cs
More file actions
150 lines (134 loc) · 5.21 KB
/
Copy pathBroadcastScheduler.cs
File metadata and controls
150 lines (134 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
namespace WpfApp1
{
/// <summary>
/// 广播调度管理类,负责管理和调度广播播放
/// </summary>
public class BroadcastScheduler
{
private IScheduler _scheduler;
private MainWindow _mainWindow;
/// <summary>
/// 创建广播调度器
/// </summary>
/// <param name="mainWindow">主窗口引用</param>
public BroadcastScheduler(MainWindow mainWindow)
{
_mainWindow = mainWindow;
}
/// <summary>
/// 初始化调度器
/// </summary>
public async Task Initialize()
{
try
{
// 创建调度器工厂
StdSchedulerFactory factory = new StdSchedulerFactory();
// 获取调度器
_scheduler = await factory.GetScheduler();
// 将MainWindow实例放入调度器上下文
_scheduler.Context.Put("mainWindow", _mainWindow);
// 启动调度器
await _scheduler.Start();
// 创建每日检查任务(每秒检查一次,用于确保高精度触发)
IJobDetail job = JobBuilder.Create<CheckBroadcastJob>()
.WithIdentity("checkBroadcastJob", "broadcast")
.Build();
// 创建触发器(每秒触发一次)
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("checkBroadcastTrigger", "broadcast")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(1)
.RepeatForever())
.Build();
// 将任务和触发器添加到调度器
await _scheduler.ScheduleJob(job, trigger);
}
catch (Exception ex)
{
throw new Exception($"初始化调度器失败: {ex.Message}", ex);
}
}
/// <summary>
/// 找出下一个要播放的广播项目
/// </summary>
/// <param name="items">广播项目集合</param>
/// <param name="now">当前时间</param>
/// <returns>下一个要播放的项目及时间</returns>
public (BroadcastItem Item, TimeSpan TimeUntil)? FindNextBroadcast(ObservableCollection<BroadcastItem> items, DateTime now)
{
return BroadcastScheduleMatcher.FindNextBroadcast(items, now);
}
/// <summary>
/// 获取下一个要播放的广播项目
/// </summary>
/// <param name="items">广播项目集合</param>
/// <param name="now">当前时间</param>
/// <returns>下一个要播放的项目</returns>
public BroadcastItem? GetNextBroadcast(ObservableCollection<BroadcastItem> items, DateTime now)
{
return BroadcastScheduleMatcher.GetNextBroadcast(items, now);
}
/// <summary>
/// 获取距离下一个广播的时间
/// </summary>
/// <param name="item">广播项目</param>
/// <param name="now">当前时间</param>
/// <returns>距离下一次播放的时间</returns>
public TimeSpan GetTimeUntilNextBroadcast(BroadcastItem item, DateTime now)
{
return BroadcastScheduleMatcher.GetTimeUntilNextBroadcast(item, now);
}
/// <summary>
/// 判断某个星期是否已安排播放
/// </summary>
/// <param name="item">广播项目</param>
/// <param name="dayOfWeek">星期</param>
/// <returns>是否安排播放</returns>
public bool IsDayScheduled(BroadcastItem item, DayOfWeek dayOfWeek)
{
return BroadcastScheduleMatcher.IsDayScheduled(item, dayOfWeek);
}
/// <summary>
/// 排序广播项目
/// </summary>
/// <param name="items">广播项目集合</param>
public void SortBroadcastItems(ObservableCollection<BroadcastItem> items)
{
BroadcastScheduleMatcher.SortBroadcastItems(items);
}
/// <summary>
/// 重新调度所有任务
/// </summary>
/// <param name="items">广播项目集合</param>
public void RescheduleAllJobs(ObservableCollection<BroadcastItem> items)
{
// 由于我们使用的是轮询检查而不是直接调度,此方法可简单实现
// 实际上是通过CheckBroadcastJob每秒检查一次是否有广播要播放
// 这里可以添加其他调度相关的逻辑
}
/// <summary>
/// 关闭调度器
/// </summary>
public void Shutdown()
{
try
{
if (_scheduler != null)
{
_scheduler.Shutdown(waitForJobsToComplete: false).ConfigureAwait(false).GetAwaiter().GetResult();
}
}
catch
{
// 忽略关闭时的异常
}
}
}
}