.net core WebApi ManualResetEvent实现并发同步

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

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

请看如下代码:

private static ManualResetEvent mre = new ManualResetEvent(true);
static void Main(string[] args)
{
            //释放信号量
            mre.Reset();
            for (int i = 0; i < 3; i++)
            {
                Thread t = new Thread(ManualSubFuncTest);
                t.Name = $"Thread.{i}";
                t.Start();
            }
            Thread.SpinWait(10);
            Console.WriteLine("all threads have started,please waiting for 3 seconds...");
            Thread.Sleep(3000);
            //获取信号量
            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;//1:空闲 0:非空闲
        protected static ManualResetEvent Mre=new ManualResetEvent(false);
        public ResponseModel SynchronizationTest() {
            ResponseModel rc = new ResponseModel(0, "初始化");

            try
            {
                Mre.Reset();
                //如果其他线程正在操作,则等待,5秒后超时
                if (Interlocked.CompareExchange(ref Counter, 0, 1) == 0)
                   Mre.WaitOne(3000);

                int count = RedisHelper.Get(GoodsNumberKey).ToInt32();
                if (count > 0) {
                    RedisHelper.Set(GoodsNumberKey, "-1");
                    rc.SetMessage("重置成功!");
                }
                else rc.SetMessage("已被重置,本次重置无效");
            }
            catch (Exception ex) {
                _log.Error(ex);
            }
            finally {
                //转为空闲状态
                Interlocked.Exchange(ref Counter, 1);
                //设置信号量,让上面的 Mre.Wait(3000);取消等待,继续执行代码
                Mre.Set();
            }

            return rc;
        }

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

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

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

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

原文地址:https://www.cnblogs.com/williamwsj/p/9722976.html

时间: 2024-10-12 07:30:35

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

.Net Core WebAPI 基于Task的同步&amp;异步编程

await 和 async  异步的实质就是线程的切换(遇到await),同一请求下,异步和同步的执行时间是一样的,但有人说异步可以提高XXX性能,但具体是什么性能呢?又说不上来,其实就只提高并发量,并不能提升你应用程序处理的速度 使用异步的目的是用尽量少的线程保证相同的并发量. 线程的总数少了,线程切换消耗的资源就小了,相对来提供给客户任务的资源就多了,性能就在这里. CPU 在大量线程的情况下,20%的时间片在线程切换上,客户任务有80%的资源使用. 减少了线程数,只有5%的时间片消耗在线程

Net Core WebAPI

Net Core WebAPI .Net Core WebAPI 基于Task的同步&异步编程快速入门 Task.Result async & await 总结 并行任务(Task)以及基于Task的异步编程(asynchronously)在.NET Framework早已使用多年,而在微软新推出的.NET Core 平台下也有相同功能的实现,本文将通过.NET Core WebAPI,介绍使用Task.result的同步编程以及使用await的异步编程模型. Task.Result Re

【免费视频】使用VS Code开发ASP.NET Core WebAPI应用程序

1.使用VS Code开发ASP.NET Core WebAPI应用程序 1.使用Visual Studio Code开发Asp.Net Core基础入门实战 毕竟从.net过度过来的我们已经习惯了使用Microsoft的Visual Studio进行开发.那么有没有一款媲美Visual Studio的开发工具可以让我们能够在Linux系统上进行高效的.NET Core开发呢?答案是肯定的,因为微软已经开发了一个名为Visual Studio Code的跨平台和开源的文本编辑器.Visual S

net core WebApi——April.Util更新之权限

目录 前言 权限 中间层 小结 前言 在之前已经提到过,公用类库Util已经开源,目的一是为了简化开发的工作量,毕竟有些常规的功能类库重复率还是挺高的,二是为了一起探讨学习软件开发,用的人越多问题也就会越多,解决的问题越多功能也就越完善,仓库地址: April.Util_github,April.Util_gitee,还没关注的朋友希望可以先mark,后续会持续维护. 权限 在之前的net core WebApi--公用库April.Util公开及发布中已经介绍了初次发布的一些功能,其中包括缓存

简单的多线程并发同步演示

#include "stdafx.h"#include <iostream>#include <Windows.h>using namespace std;HANDLE hMutex;DWORD WINAPI Fun(LPVOID lp){    while(1){        WaitForSingleObject(hMutex,INFINITE);        cout<<"fun"<<endl;//如果不用信

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

WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在线调试. 那么要讲Swagger应用到Asp.net Core中需要哪些步骤,填多少坑呢? 安装Swagger到项目 { "dependencies": { "Swashbuckle": "6.0.0-beta902", ........ 或者直接通

数据量下高并发同步的讲解(不看,保证你后悔

4.常见的提高高并发下访问的效率的手段 首先要了解高并发的的瓶颈在哪里? 1.可能是服务器网络带宽不够 2.可能web线程连接数不够 3.可能数据库连接查询上不去. 根据不同的情况,解决思路也不同. 像第一种情况可以增加网络带宽,DNS域名解析分发多台服务器. 负载均衡,前置代理服务器nginx.apache等等 数据库查询优化,读写分离,分表等等 最后复制一些在高并发下面需要常常需要处理的内容: 尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能.

大数据量下高并发同步的讲解

对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究一下常见的并发和同步吧. 为了更好的理解并发和同步,我们需要先明白两个重要的概念:同步和异步    1.同步和异步的区别和联系         所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到 返回的值或消息后才往下执行其它的命令. 异步,

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

前几天,按照AngularJS2的英雄指南教程走了一遍,教程网址是http://origin.angular.live/docs/ts/latest/tutorial/. 在步骤完成后,又更进一步,在英雄增删改的时候,直接调用.net core的WebApi来实现后台数据的操作,替换教程中的模拟WebApi方式.在替换.net core WebApi时,还是遇到了一些坑的,这里记录一下. 先来看一下WebApi和AngularJS的源代码: WebApi 1 [Route("api/[contr