第16章 注销器移除缓存数据

注销器的另1个用途是: 通过触发器(EventPublisher)的实例,调用继承于注销器接口的指定具体实现类(StateCacheEventConsumer)中的方法(HandleEventAsync),来删除Redis中的缓存的省/直辖市的所有实例及其键之后,重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

1 StateAddEvent

using Linkage.Domain.Directory;

namespace Linkage.Events

{

    /// <summary>

    /// 【省/直辖市添加触发--类】

    /// 摘要:

    ///     通过该构造方法中的参数实例,来实例化该类中的同类型属性成员。

    /// </summary>

    public class StateAddEvent

    {

        #region 变量--拷贝构造方法

        /// <param name="stateIntance">省/直辖市实体的1个指定实例。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// </summary

        /// <remarks>

        /// 摘要:

        ///     通过该构造方法中的参数实例,来实例化该类中的同类型属性成员。

        /// </remarks>

        public StateAddEvent(State stateIntance)

        {

            StateIntance = stateIntance;

        }

        #endregion

        #region 属性

        /// <summary>

        /// 【单个省/直辖市】

        /// <remarks>

        /// 摘要:

        ///     获取/设置省/直辖市实体的1个指定实例。

        /// </remarks>

        /// </summary>

        public State StateIntance { get; }

        #endregion

    }

}

2 StateCacheEventConsumer

using Linkage.Events;

using Microsoft.Extensions.Caching.Distributed;

namespace Linkage.Caching

{

    /// <summary>

    /// 【省/直辖市注销器--类】

    /// 摘要:

    ///    在执行省/直辖市的插入操作之后,通过触发器实例,调用当前类中的方法(HandleEventAsync),来删除Redis中的缓存的省/直辖市的所有实例及其键之后,

    /// 重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    /// </summary>

    public class StateCacheEventConsumer : IConsumer<StateAddEvent>

    {

        #region 变量--拷贝构造方法

        private readonly IDistributedCache _distributedCache;

        public StateCacheEventConsumer(IDistributedCache distributedCache)

        {

            _distributedCache = distributedCache;

        }

        #endregion

        #region 方法

        /// <param name="eventMessage">省/直辖插入类的1个指定实例。</param>

        /// <summary>

        /// 【异步触发句柄】

        /// <remarks>

        /// 摘要:

        ///      在执行省/直辖市的插入操作之后,通过触发器实例,调用当前方法,来删除Redis中的缓存的省/直辖市的所有实例及其键之后,

        /// 重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        /// </remarks>

        /// </summary>

        public async Task HandleEventAsync(StateAddEvent eventMessage)

        {

            await _distributedCache.RemoveAsync("StateAll");

        }

        #endregion

    }

}

3 CachingConsumerController

using Linkage.Data;

using Linkage.Domain.Directory;

using Linkage.Events;

using Linkage.Models;

using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.Caching.Distributed;

using Newtonsoft.Json;

namespace Linkage.Controllers

{

    public class CachingConsumerController : Controller

    {

        private readonly EFCoreContext _context;

        private readonly IDistributedCache _distributedCache;

        private readonly IEventPublisher _eventPublisher;

        public CachingConsumerController(

            EFCoreContext context,

            IDistributedCache distributedCache,

            IEventPublisher eventPublisher)

        {

            _context = context;

            _distributedCache = distributedCache;

            _eventPublisher = eventPublisher;

        }

        public async Task<IActionResult> Index()

        {

            StateModel _stateModel = new StateModel();

            if (await _distributedCache.GetStringAsync("StateAll") == null)

            {

                await _distributedCache.SetStringAsync("StateAll",

                    JsonConvert.SerializeObject(await _context.StateDbSet.ToListAsync()),

                    new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300) });

              

            }

            _stateModel.StateList = JsonConvert.DeserializeObject<List<State>>(await _distributedCache.GetStringAsync("StateAll"));

            return View(_stateModel);

        }

        [HttpPost]

        public async Task<IActionResult> RelayRenderAjax(StateModel stateModel)

        {

            State _state = new State();

            _state.Name = stateModel.Name;

            await _context.StateDbSet.AddAsync(_state);

            await _context.SaveChangesAsync();

            return Json(true);

        }

        [HttpPost]

        public async Task<IActionResult> PromptlyRenderAjax(StateModel stateModel)

        {

            State _state = new State();

            _state.Name = stateModel.Name;

            await _context.StateDbSet.AddAsync(_state);

            await _context.SaveChangesAsync();

            //通过触发器实例,调用继承于注销器接口的指定具体实现类(StateCacheEventConsumer)中的方法(HandleEventAsync),来删除Redis中的缓存的省/直辖市的所有实例及其键之后,

            //重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

            await _eventPublisher.PublishAsync(new StateAddEvent(_state));

            return Json(true);

        }

    }

}

4 CachingConsumer\Index.cshtml

@model Linkage.Models.StateModel

@{

    ViewData["Title"] = "注销器注销缓存数据";

}

<div class="row">

    <div class="col-md-12">

        <form id="AddState">

            <div class="form-group">

                <label asp-for="Name" class="control-label"></label>

                <input asp-for="Name" class="form-control" />

                <span asp-validation-for="Name" class="text-danger"></span>

            </div>

            <div class="form-group text-center col-12 mt-3">

                <button type="button" id="RelayRender" class="btn btn-dark me-5">

                    页面在<span class="fw-bolder text-danger">【延时5分钟后】</span>才能渲染显示添加数据

                </button>

                <button type="button" id="PromptlyRender" class="btn btn-dark">

                    页面在<span class="fw-bolder text-success">【添加后立即】</span>渲染显示添加数据

                </button>

            </div>

        </form>

    </div>

</div>

<div id="remainTime" class="text-danger text-center fw-bolder fs-2"></div>

<div class="row mt-3">

    <table class="table">

        <thead>

            <tr>

                <th scope="col">编号</th>

                <th scope="col">省/直辖市</th>

            </tr>

        </thead>

        <tbody>

        @{

            if (Model.StateList == null || Model.StateList.Count <= 0)

            {

                <tr>

                    <td colspan="2"><h1 class="text-danger text-center">暂无数据</h1></td>

                </tr>

            }

            else

            {

                foreach (var item in Model.StateList)

                {

                    <tr>

                        <td>@item.Id</td>

                        <td>@item.Name</td>

                    </tr>

                }

            }

        }

        </tbody>

    </table>

</div>

@section Scripts {

    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

    <script type="text/javascript">

        var SysSecond;

        var InterValObj;

        $(document).ready(function () {

            SysSecond = 330; //这里获取倒计时的起始时间

            InterValObj = window.setInterval(SetRemainTime, 1000); //间隔函数,1秒执行

        });

        //将时间减去1秒,计算天、时、分、秒

        function SetRemainTime() {

            if (SysSecond > 0) {

                SysSecond = SysSecond - 1;

                var second = Math.floor(SysSecond % 60);            // 计算秒

                var minite = Math.floor((SysSecond / 60) % 60);      //计算分

                var hour = Math.floor((SysSecond / 3600) % 24);      //计算小时

                var day = Math.floor((SysSecond / 3600) / 24);       //计算天

                var hourDiv = "<span id='hourSpan'>" + hour + "小时" + "</span>";

                var dayDiv = "<span id='daySpan'>" + day + "天" + "</span>";

                $("#remainTime").html(dayDiv + hourDiv + minite + "分" + second + "秒");

                if (hour === 0) {//当不足1小时时隐藏小时

                    $('#hourSpan').css('display', 'none');

                }

                if (day === 0) {//当不足1天时隐藏天

                    $('#daySpan').css('display', 'none');

                }

            } else {//剩余时间小于或等于0的时候,就停止间隔函数

                window.clearInterval(InterValObj);

                if (SysSecond <= 0) {

                    window.location.href = "/CachingConsumer/Index";

                }

                //这里可以添加倒计时时间为0后需要执行的事件

               // alert("时间为0");

            }

        }

        // 页面在【延时5分钟后】才能渲染显示添加数据

        $("#RelayRender").on("click", function () {

            if ($("#Name").val() == "" || $("#Name").val() == null) {

                alert("省/直辖市不能为空!");

                return;

            }

            $.ajax({

                url: "/CachingConsumer/RelayRenderAjax",

                type: "POST",

                datatype: "JSON",

                cache: false//禁用缓存。

                data: $("#AddState").serialize(),

                success: function (data) {

                    window.location.href = "/CachingConsumer/Index";

                }

            });

        });

        // 页面在【添加后立即】渲染显示添加数据

        $("#PromptlyRender").on("click", function () {

            if ($("#Name").val() == "" || $("#Name").val() == null) {

                alert("省/直辖市不能为空!");

                return;

            }

            $.ajax({

                url: "/CachingConsumer/PromptlyRenderAjax",

                type: "POST",

                datatype: "JSON",

                cache: false//禁用缓存。

                data: $("#AddState").serialize(),

                success: function (data) {

                    window.location.href = "/CachingConsumer/Index";

                }

            });

        });

    </script>

}

对以上功能更为具体实现和注释见:221028_16Linkage(注销器移除缓存数据)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值