.NET分布式Orleans計(jì)時(shí)器和提醒功能實(shí)現(xiàn)
Timer是什么
Timer 是一種用于創(chuàng)建定期粒度行為的機(jī)制。
與標(biāo)準(zhǔn)的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時(shí)間后執(zhí)行特定的操作,或者在特定的時(shí)間間隔內(nèi)重復(fù)執(zhí)行操作。
它在分布式系統(tǒng)中具有重要作用,特別是在處理需要周期性執(zhí)行的任務(wù)時(shí)非常有用。
Timer的注意事項(xiàng)
計(jì)時(shí)器回調(diào)不會(huì)改變空閑激活的狀態(tài),不能用于推遲其他空閑激活的停用。
Grain.RegisterTimer 中傳遞的時(shí)間段取決于上次回調(diào)完成到下一次回調(diào)開始的時(shí)間,因此回調(diào)的頻率會(huì)受到執(zhí)行時(shí)間的影響。
每次 asyncCallback 調(diào)用都會(huì)作為單獨(dú)輪次的激活,并且不會(huì)與同一激活的其他輪次同時(shí)運(yùn)行。
代碼示例
public class PlayerGrain : Grain, IPlayerGrain
{
public Task<string> GetPlayerInfo()
{
var timer = RegisterTimer(DoSomething, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
return Task.FromResult($"Player ID: {this.GetPrimaryKeyString()}");
}
private async Task DoSomething(object state)
{
// 在這里定義要執(zhí)行的操作
await Task.Delay(5000);
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} Timer Triggered: {this.GetPrimaryKeyString()}");
}
}
Reminder與Timer的區(qū)別
提醒(Reminder)是一種在 Orleans 中用于處理周期性任務(wù)的機(jī)制,與計(jì)時(shí)器類似,但具有一些重要區(qū)別:
永久性觸發(fā):提醒是永久性的,除非明確取消,否則會(huì)在幾乎所有情況下(包括部分或完整群集重啟)繼續(xù)觸發(fā)。
定義的持久性:提醒的定義會(huì)寫入存儲(chǔ),但具體的事件及其時(shí)間不會(huì)。這意味著如果群集在提醒應(yīng)該觸發(fā)時(shí)關(guān)閉,它將錯(cuò)過該提醒,只會(huì)在下次提醒的觸發(fā)時(shí)被重新激活。
關(guān)聯(lián)于Grain:提醒是與Grain關(guān)聯(lián)的,而不是與任何特定激活Grain。如果提醒的觸發(fā)時(shí),粒度沒有與之關(guān)聯(lián)的激活,則會(huì)創(chuàng)建該Grain,并在下次觸發(fā)時(shí)重新激活。
消息傳遞:提醒的傳遞通過消息發(fā)生,受到與所有其他粒度方法相同的交錯(cuò)語義的約束。
適用場景:提醒通常不適用于高頻計(jì)時(shí)器,其周期應(yīng)該以分鐘、小時(shí)或天為單位。相比之下,提醒更適用于周期性任務(wù)的處理,例如定期執(zhí)行清理任務(wù)或發(fā)送通知等。
如果想使用reminder,需要安裝nuget包
<PackageReference Include="Microsoft.Orleans.Reminders" Version="8.0.0" />
并開啟reminder
silBuilder.UseInMemoryReminderService();
Grain需要實(shí)現(xiàn)接口 IRemindable ,并使用this.RegisterOrUpdateReminder 注冊reminder
public interface IPlayerGrain : IGrainWithStringKey, IRemindable
{
Task<string> GetPlayerInfo();
}
public class PlayerGrain : Grain, IPlayerGrain
{
public Task<string> GetPlayerInfo()
{
this.RegisterOrUpdateReminder("myReminder", TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(1));
return Task.FromResult($"Player ID: {this.GetPrimaryKeyString()}");
}
public Task ReceiveReminder(string reminderName, TickStatus status)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} Reminder Triggered: {this.GetPrimaryKeyString()}");return Task.CompletedTask;
}
}
Timer 和 Reminder 場景
使用定時(shí)器(Timer)的場景:
- 對(duì)激活狀態(tài)的要求不高:如果激活被停用或發(fā)生故障時(shí),計(jì)時(shí)器停止運(yùn)行不會(huì)產(chǎn)生重大影響,或者這種行為可接受。
- 較小的分辨率:如果需要較小的時(shí)間間隔來執(zhí)行任務(wù),例如以秒或分鐘為單位。
- 計(jì)時(shí)器回調(diào)與 Grain 生命周期相關(guān):如果需要在 Grain 的生命周期事件(如OnActivateAsync())或者調(diào)用粒度方法時(shí)啟動(dòng)計(jì)時(shí)器回調(diào)。
使用提醒(Reminder)的場景:
- 持久性要求:當(dāng)需要確保周期性行為在激活和任何故障中都存在時(shí),提醒是一個(gè)更好的選擇。因?yàn)樘嵝咽怯谰眯缘?,除非明確取消,否則會(huì)在幾乎所有情況下繼續(xù)觸發(fā)。
- 較大的時(shí)間間隔:當(dāng)執(zhí)行不常見的任務(wù),例如以分鐘、小時(shí)或天為單位的周期性任務(wù)時(shí),提醒更為適合。
依賴注入創(chuàng)建Timer與Reminder
將 ITimerRegistry 或 IReminderRegistry 注入粒度的構(gòu)造函數(shù)中,也可以創(chuàng)建Timer與Reminder
public PlayerGrain(ITimerRegistry timerRegistry,
IReminderRegistry reminderRegistry,
IGrainContext grainContext)
{
timerRegistry.RegisterTimer(grainContext,DoSomething,null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
reminderRegistry.RegisterOrUpdateReminder(grainContext.GrainId,"testreminder",TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(1));
}
到此這篇關(guān)于.NET分布式Orleans - 4 - 計(jì)時(shí)器和提醒的文章就介紹到這了,更多相關(guān).NET計(jì)時(shí)器和提醒內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用C#中的params關(guān)鍵字實(shí)現(xiàn)方法形參個(gè)數(shù)可變
個(gè)人認(rèn)為,提供params關(guān)鍵字以實(shí)現(xiàn)方法形參個(gè)數(shù)可變是C#語法的一大優(yōu)點(diǎn)。在方法形參列表中,數(shù)組類型的參數(shù)前加params關(guān)鍵字,通??梢栽谡{(diào)用方法時(shí)代碼更加精練2012-01-01
ASP.NET MVC重寫RazorViewEngine實(shí)現(xiàn)多主題切換
這篇文章主要為大家詳細(xì)介紹了ASP.NET MVC重寫RazorViewEngine實(shí)現(xiàn)多主題切換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
ASP.NET?Core中MVC模式實(shí)現(xiàn)路由一
這篇文章介紹了ASP.NET?Core中MVC模式實(shí)現(xiàn)路由的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04

