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

一、在控制台应用程序中测试

请看如下代码:

private static ManualResetEvent mre = new ManualResetEvent(true);
static void Main(string[] args)
{
//释放信号量
mre.Reset();
for (int i = ; i < ; i++)
{
Thread t = new Thread(ManualSubFuncTest);
t.Name = $"Thread.{i}";
t.Start();
}
Thread.SpinWait();
Console.WriteLine("all threads have started,please waiting for 3 seconds...");
Thread.Sleep();
//获取信号量
mre.Set(); Console.ReadKey();
} static void ManualSubFuncTest()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine($"{name} starts and calling waitone() method " );
//如果mre不拥有信号量,则等待,否则继续执行
mre.WaitOne();
Console.WriteLine($"{name} ends");
}

结果如下图所示:

测试结果和预期一样。

二、在webapi项目中测试

代码如下:

       [HttpGet("[controller]/v1/api/[action]")]
public IActionResult Test() {
return Json(SynchronizationTest());
} protected static int Counter = ;//1:空闲 0:非空闲
protected static ManualResetEvent Mre=new ManualResetEvent(false);
public ResponseModel SynchronizationTest() {
ResponseModel rc = new ResponseModel(, "初始化"); try
{
Mre.Reset();
//如果其他线程正在操作,则等待,5秒后超时
if (Interlocked.CompareExchange(ref Counter, , ) == )
Mre.WaitOne(3000); 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, );
//设置信号量,让上面的 Mre.Wait(3000);取消等待,继续执行代码
Mre.Set();
} return rc;
}

接下来,我们连续发送8次请求,看看结果如何:

由结果可以看到,多个线程中,只有一个线程操作成功,起到了并发同步的目的。

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

如果是轻量化的线程间同步操作,建议用ManualResetEventSlim。其效果和ManualResetEvent是一样的,可以去看看我的《.net core WebApi Interlocked配合ManualResetEventSlim实现并发同步》这篇随笔。

.net core WebApi ManualResetEvent实现并发同步的更多相关文章

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

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

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

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

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

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

  4. Net Core WebAPI

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

  5. .net core WebApi Interlocked配合ManualResetEventSlim实现并发同步

    由于项目有某种需求,在WebApi中,有大量的请求需要操作相同的数据,因此需要用到并发同步机制去操作共享的数据. 本次配合使用Interlocked和ManualResetEventSlim来实现并发 ...

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

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

  7. ASP.NET Core WebAPI控制器返回类型的最佳选项

    前言 从.NET Core 2.1版开始,到目前为止,控制器操作可以返回三种类型的WebApi响应.这三种类型都有自己的优点和缺点,但都缺乏满足REST和高可测性的选项. ASP.NET Core中可 ...

  8. ASP.NET Core WebApi使用Swagger生成api说明文档

    1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...

  9. 使用 xUnit 编写 ASP.NET Core WebAPI单元测试

    本文使用xUnit对ASP.NET Core WebAPI做单元测试,使用HttpClient的同步和异步请求,下面详细介绍xUnit的使用过程: 一.创建示例项目 模板为我们自动创建了一个Value ...

随机推荐

  1. python面试问题集锦

    GIL(全局解释器锁) 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. 1.python语 ...

  2. Nodejs运行错误小结

    (迁移自旧博客2017 04 15) 在使用过程中会遇到一些问题,学习过程中不定期更新. 问题一 错误如下 **events.js:72 throw er; // Unhandled 'error' ...

  3. 比原链(Bytom)先知节点 Ubuntu接入文档

    系统要求 我们建议选择知名的VPS服务商,运行比原链节点对算力没有要求,但是请配置尽可能大的磁盘空间. 节点服务器最小配置: 操作系统: Windows/Linux/Docker CPU: 2核 内存 ...

  4. Lintcode155-Minimum Depth of Binary Tree-Easy

    155. Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum depth is ...

  5. swift 有道 翻译文档(1 定义变量常量,数组字典)

    使用let来创建常量,使用var来创建变量.一个常量的值在编译时不需要知道,但是您必须为它指定一个值一次.这意味着您可以使用常量来命名一个您确定一次的值,但是在许多地方使用它.var myVariab ...

  6. Unity自定义定时器,模拟协程,脱离MonoBehavior控制

    using System; using System.Collections.Generic; using System.Timers; public class PETimer { private ...

  7. 四、Python数据类型(二)

    一.布尔(Boolean) 布尔类型的数据只有两个:(真)True和(假)False.多用于条件语句或者是作为函数返回值. 二.字典(dictionary) 1.认识字典 将数据组织成键值对(key- ...

  8. vue全局组件-父子组件传值

    全局组件注册方式:Vue.component(组件名,{方法}) demo: 子组件:upload.vue <template> <div > <div class=&q ...

  9. vue入门练习(一)

    1.安装node,webpack node -v //查看已安装版本 npm install -g webpack  //安装webpack npm install -g webpack-dev-se ...

  10. mysql主从同步与读写分离

    为了解决数据库服务的高可用问题以及负载均衡问题, 1正常情况下可以互为主从,均衡分担数据流量, 2防止数据库服务器在宕机的情况下可以顺利切换到正常的数据库服务器,减少公司的客户流量损失故公司需要搭建数 ...