在ASP Net Core 2 MVC应用程序中,我使用this BackGroundService
(通过IHostingService
)和以下实现来更新实时仪表板的单一规格对象。但是,我不知道确保捕获Update
事件被触发时抛出的任何异常的好方法。
注意:我知道AppDomain.UnhandledException
,但发现它更像是一个大锤的方法,并希望更容易维护和扩展。
或者,是否有更好的方法来定期更新ASP.NET Core 2
中后台任务中的数据?
public class GaugeUpdater : BackgroundService
{
private readonly List<IUpdateable> _updatables;
private Timer _timer;
public GaugeUpdater (IEnumerable<IUpdateable> updateables)
{
_updatables = updateables.ToList();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!stoppingToken.IsCancellationRequested)
{
await InitializeUpdateables();
SetTimer();
}
}
private void SetTimer()
{
const int intervalMilliseconds = 60_000;
var interval = new TimeSpan(0, 0, 0, 0, intervalMilliseconds);
_timer = new Timer(UpdateAll, null, interval, interval);
}
private async Task InitializeUpdateables()
{
var tasks = _updatables.Select(x => x.Initialize()).ToList();
await Task.WhenAll(tasks);
}
private async void UpdateAll(object state)
{
// TODO: Find way to handle exceptions, as awaiting async void makes it impossible for caller to catch.
// AppDomain.UnhandledException is possible but hard to maintain and handle in this scope.
_updatables.ForEach(async x => await x.Update());
}
}
答案 0 :(得分:0)
async void
可以用于事件处理程序。创建和事件并使用计时器提升它。从那里你应该能够等待异步任务并处理异常
public class GaugeUpdater : BackgroundService {
private readonly List<IUpdateable> _updatables;
private Timer _timer;
public GaugeUpdater (IEnumerable<IUpdateable> updateables) {
_updatables = updateables.ToList();
Updating += OnUpdating; //Subscribe to event
}
private event EventHandler Updating = delegate { };
private async void OnUpdating(object sender, EventArgs args) {
try {
var tasks = _updatables.Select(x => x.Update());
await Task.WhenAll(tasks);
} catch {
//TODO: Logging???
}
}
private void UpdateAll(object state) {
Updating(this, EventArgs.Empty); //Raise event
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
if (!stoppingToken.IsCancellationRequested) {
await InitializeUpdateables();
SetTimer();
}
}
private void SetTimer() {
const int intervalMilliseconds = 60_000;
var interval = new TimeSpan(0, 0, 0, 0, intervalMilliseconds);
_timer = new Timer(UpdateAll, null, interval, interval);
}
private async Task InitializeUpdateables() {
var tasks = _updatables.Select(x => x.Initialize()).ToList();
await Task.WhenAll(tasks);
}
}