日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

Intro

.NET 6 中引入了一個(gè)新的 Timer ——
System.Threading.PeriodicTimer,和之前的幾個(gè) Timer 相比一個(gè)最大的區(qū)別就是,新的 PeriodicTimer 的事件處理可以比較方便地使用異步方式,消除了使用 callback 的機(jī)制,減少了使用的復(fù)雜度。

Sample

來看一個(gè)使用示例:

using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, e) =>
{
    e.Cancel = true;
    cts.Cancel();
};

using var timer = new PeriodicTimer(TimeSpan.FromSeconds(3));
try
{
    while (await timer.WaitForNextTickAsync(cts.Token))
    {
        Console.WriteLine($"Timed event triggered({DateTime.Now:HH:mm:ss})");
    }
}
catch (OperationCanceledException)
{
    Console.WriteLine("Operation cancelled");
}

通常 PeriodicTimer 可以結(jié)合 CancellationToken 一起使用,和 CancellationToken 一起用的時(shí)候需要注意,如果 cancellationToken 被取消的時(shí)候會(huì)拋出一個(gè)
OperationCanceledException 需要考慮自己處理異常

除此之外如果 PeriodicTimer 被 Dispose,這個(gè) timer 就相當(dāng)于是失效的,并且無法重新恢復(fù),來看下面這個(gè)示例:

var timer1 = new PeriodicTimer(TimeSpan.FromSeconds(2));
timer1.Dispose();
if (await timer1.WaitForNextTickAsync())
{
    Console.WriteLine("Timer1 event triggered");
}

上面這樣的一段代碼,在 WaitForNextTickAsync 之前就已經(jīng)調(diào)用了 Dispose(),此時(shí) WaitForNextTickAsync 方法會(huì)始終返回 false ,所以 Console.WriteLine 的邏輯也不會(huì)被執(zhí)行

我們之前會(huì)嘗試使用 Timer 來做一些后臺(tái)任務(wù),可以改造成使用新的 PeriodicTimer 來實(shí)現(xiàn),小示例如下:

public abstract class TimerScheduledService : BackgroundService
{
    private readonly PeriodicTimer _timer;
    private readonly TimeSpan _period;
    protected readonly ILogger Logger;

    protected TimerScheduledService(TimeSpan period, ILogger logger)
    {
        Logger = logger;
        _period = period;
        _timer = new PeriodicTimer(_period);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            while (await _timer.WaitForNextTickAsync(stoppingToken))
            {
                try
                {
                    Logger.LogInformation("Begin execute service");
                    await ExecuteInternal(stoppingToken);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Execute exception");
                }
                finally
                {
                    Logger.LogInformation("Execute finished");
                }
            }
        }
        catch (OperationCanceledException operationCancelledException)
        {
            Logger.LogWarning(operationCancelledException, "service stopped");
        }
    }

    protected abstract Task ExecuteInternal(CancellationToken stoppingToken);

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        Logger.LogInformation("Service is stopping.");
        _timer.Dispose();
        return base.StopAsync(cancellationToken);
    }
}

實(shí)現(xiàn)示例如下:

public class TimedHealthCheckService : TimerScheduledService
{
    public TimedHealthCheckService(ILogger<TimedHealthCheckService> logger) : base(TimeSpan.FromSeconds(5), logger)
    {
    }

    protected override Task ExecuteInternal(CancellationToken stoppingToken)
    {
        Logger.LogInformation("Executing...");
        return Task.CompletedTask;
    }
}

運(yùn)行輸出如下:

.NET 6 新特性 PeriodicTimer

 

More

新的 PeriodicTimer 相比之前的幾個(gè) Timer 來說,有下面幾個(gè)特點(diǎn)

  • 沒有 callback 來綁定事件
  • 不會(huì)發(fā)生重入,只允許有一個(gè)消費(fèi)者,不允許同一個(gè) PeriodicTimer 在不同的地方同時(shí) WaitForNextTickAsync,不需要自己做排他鎖來實(shí)現(xiàn)不能重入
  • 異步化,之前的幾個(gè) timer 的 callback 都是同步的,使用新的 timer 我們可以更好的使用異步方法,避免寫 Sync over Async 之類的代碼
  • Dispose() 之后,該實(shí)例就無法再使用,WaitForNextTickAsync 始終返回 false

最后來做一個(gè)題目,把第一個(gè)示例改造一下,最終代碼如下:

using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(30));
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(3));
try
{
    while (await timer.WaitForNextTickAsync(cts.Token))
    {
        await Task.Delay(5000);
        Console.WriteLine($"Timed event triggered({DateTime.Now:HH:mm:ss})");
    }
}
catch (OperationCanceledException)
{
    Console.WriteLine("Operation cancelled");
}

猜一下輸出結(jié)果是什么,Timed event triggered 會(huì)輸出幾次

.NET 6 新特性 PeriodicTimer

 

References

  • https://www.ilkayilknur.com/a-new-modern-timer-api-in-dotnet-6-periodictimer
  • https://docs.microsoft.com/en-us/dotnet/api/system.threading.periodictimer?view=net-6.0
  • https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/Threading/PeriodicTimer.cs
  • https://github.com/dotnet/runtime/issues/31525
  • https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/PeriodicTimerSample/Program.cs
  • https://github.com/OpenReservation/ReservationServer/blob/dev/OpenReservation.Helper/Services/CronScheduleServiceBase.cs#L91

分享到:
標(biāo)簽:NET
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定