由于项目有某种需求,在WebApi中,有大量的请求需要操作相同的数据,因此需要用到并发同步机制去操作共享的数据。

本次配合使用Interlocked和ManualResetEventSlim来实现并发同步的目的。

Interlocked实现了原子性的操作,ManualResetEventSlim提供信号量等待唤醒机制。

以上两个关键字,自行找度娘了解。

代码如下:

        [HttpGet("[controller]/v1/api/[action]")]
public IActionResult Test() {
return Json(SynchronizationTest());
} protected static int Counter = ;//1:空闲 0:非空闲
protected static ManualResetEventSlim Mres = new ManualResetEventSlim(false);
public ResponseModel SynchronizationTest() {
ResponseModel rc = new ResponseModel(, "初始化"); try {
//重置信号量,相当于灭灯
Mres.Reset();
//如果其他线程正在操作,则等待,5秒后超时
if (Interlocked.CompareExchange(ref Counter, , ) == )
Mres.Wait(); int count = RedisHelper.Get(GoodsNumberKey).ToInt32();
if (count > ) {
RedisHelper.Set(GoodsNumberKey, "-1");
rc.SetMessage("重置成功!");
}
else rc.SetMessage("已被重置,本次重置无效");
}
catch (Exception ex) {
_log.Error(ex);
}
finally {
//转为空闲状态
Interlocked.Exchange(ref Counter, );
//设置信号量,让上面的 Mres.Wait(5000);取消等待,继续执行代码。相当于亮灯
Mres.Set();
} return rc;
}

逻辑是:如果Counter为0(非空闲),则证明已经有其他线程先一步进入当前逻辑,则当前线程需要等待5秒钟(5秒钟超时后继续执行代码),finally中的代码表示执行完后会将Counter置为1(空闲)并唤醒其他等待的线程,让其他线程在超时之前继续执行。

注意:信号量事件(ManualResetEventSlim)对象要用同一个的Wait、Reset和Set配合才会实现并发同步的效果。

相关代码解释:

Interlocked.CompareExchange(ref int number,int firstValue,int secondValue);该方法一共有三个参数,作用是:如果number和secondValue相等,则将firstValue引用赋值给number,否则不做任何操作,之后会返回number的原始值。参考如下代码:

int tmp = number;
ref number = number==secondValue?firstValue:number;
return tmp;

Interlocked.Exchange(ref int number,int value)的作用是将value引用赋值给number,并返回number的原始值。

ManualResetEventSlim Mres = new ManualResetEventSlim(false),ManualResetEventSlim的构造函数,如果参数为true,则当前对象拥有信号量,如果为false,则不拥有信号量。ManualResetEventSlim的作用就是通过信号量的判别,是否阻塞当前线程。如果不拥有信号量,则Wait()方法可以让当前线程阻塞,一旦拥有了信号量,就结束Wait()方法的执行,并沿着当前代码继续执行下去。

ManualResetEventSlim.Reset()的作用是释放当前事件对象的信号量,接着调用其Wait()方法会阻塞当前线程。

ManualResetEventSlim.Set()的作用是让当前事件对象拥有信号量,可以让当前线程继续执行。

.net core WebApi Interlocked配合ManualResetEventSlim实现并发同步的更多相关文章

  1. .net core WebApi ManualResetEvent实现并发同步

    ManualResetEvent,即手动重置事件,通过信号量来判别当前线程是否应该阻塞或继续执行.使用方式与ManualResetEventSlim差不多,ManualResetEventSlim只是 ...

  2. .net core WebApi Mutex实现并发同步

    Mutex,中文译为互斥体,在.net中也是作为一种线程或进程之间的互斥体存在.即在同一时刻,一个共享资源只允许被某一个线程或进程访问,其他线程或进程需要等待(直至获取互斥锁为止). Mutex的使用 ...

  3. .net core WebApi Monitor实现并发同步

    在.net中,还可以使用Monitor实现线程并发同步.Monitor类是纯托管且完全可移植,并且可能会在操作系统资源需求方面更加高效. Monitor的锁对象尽可能使用引用对象,如果是字符串或值对象 ...

  4. net core WebApi——文件分片下载

    目录 前言 开始 测试 小结 @ 前言 上一篇net core WebApi--文件分片上传与跨域请求处理介绍完文件的上传操作,本来是打算紧接着写文件下载,中间让形形色色的事给耽误的,今天还是抽个空整 ...

  5. .Net Core WebAPI 基于Task的同步&异步编程快速入门

    .Net Core WebAPI 基于Task的同步&异步编程快速入门 Task.Result async & await 总结 并行任务(Task)以及基于Task的异步编程(asy ...

  6. asp.net core webapi之跨域(Cors)访问

    这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...

  7. ASP.NET Core WebAPI 开发-新建WebAPI项目

    ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄 ...

  8. Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI

    WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...

  9. AngularJS 2调用.net core WebAPI的几个坑

    前几天,按照AngularJS2的英雄指南教程走了一遍,教程网址是http://origin.angular.live/docs/ts/latest/tutorial/. 在步骤完成后,又更进一步,在 ...

随机推荐

  1. redis示例 - 限速器,计时器

    INCR INCR key 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示 ...

  2. 如何消除img默认的间距

    方案一:div{font-size:0};方案二:img{ display:block};方案三:img{vertical-align:top;}方案四:div{ margin-bottom:-3px ...

  3. 第三章 document对象及数组

    1.数组的使用(1)声明数组var 数组名=new Array();(2)数组赋值数组名[下标]=值: 2.数组声明,分配空间,赋值同时进行var 数组名=new Array(值1,值2....)va ...

  4. ASP.NET MVC案例教程(二)

    ASP.NET MVC案例教程(二) 让第一个页面跑起来 现在,我们来实现公告系统中的第一个页面——首页.它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接.其中分类数据是用我们的Moc ...

  5. 自定义Markdown例子

    主题1 正文字体 粗体 正文行内代码 斜体 int a = 2 /*代码块*/ /*杨韬的学习备忘录*/ private void CheckCloseFigure() { if (needClose ...

  6. .net core webapi+vue 跨域访问

    最近在做一个前后端分离的示例,以下代码完美解决跨域的问题 一.后端服务 1.首先我们建一个.net core webapi的项目 2.项目引用Microsoft.AspNetCore.Cors 包 3 ...

  7. autotools源文件相同/不同目录下

    关于Autotools 我们前面的章节中已经讲到了Makefile的使用(点击进入查看文章).我们知道在Linux下面如果编译一个比较大型的项目,我们可以通过Makefile的方式来完成. 但是,我们 ...

  8. PhpStorm 2017破解

    最新版PhpStorm 2017正式版改进了PHP 7支持,改进代码完成功能. PhpStorm 是最好的PHP开发工具,使用它进行PHP开发将会让你感觉到编程的乐趣. 快乐无极终于从oschina看 ...

  9. Docker Macvlan 介绍 or 工作原理

    Docker Macvlan Network Macvlan Network:属于Docker的网络驱动. Macvlan Network:Docker主机网卡接口逻辑上分为多个子接口,每个子接口标识 ...

  10. 2018-2019-1 20189206 《Linux内核原理与分析》第八周作业

    #linux内核分析学习笔记 --第七章 可执行程序工作原理 学习目标:了解一个可执行程序是如何作为一个进程工作的. ELF文件 目标文件:是指由汇编产生的(*.o)文件和可执行文件. 即 可执行或可 ...