1. 程式人生 > >.net core WebApi並發同步

.net core WebApi並發同步

nal 項目 read 之前 狀態 sta framework result edi

由於項目有某種需求,在WebApi中,有大量的請求需要操作相同的數據,因此需要用到並發同步機制去操作共享的數據。

本次配合使用Interlocked和ManualResetEventSlim來實現並發同步的目的。

Interlocked實現了原子性的操作,ManualResetEventSlim提供信號量等待喚醒機制。

以上兩個關鍵字,自行找度娘了解。

代碼如下:

        [HttpGet("[controller]/v1/api/[action]")]
        public IActionResult Test() {
            return Json(SynchronizationTest());
        }

        
protected static int Counter = 1;//1:空閑 0:非空閑 protected static ManualResetEventSlim Mres = new ManualResetEventSlim(false); public ResponseModel SynchronizationTest() { ResponseModel rc = new ResponseModel(0, "初始化"); try { //如果其他線程正在操作,則等待,5秒後超時
if (Interlocked.CompareExchange(ref Counter, 0, 1) == 0) Mres.Wait(5000); 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); //設置信號量,讓上面的 Mres.Wait(5000);取消等待,繼續執行代碼 Mres.Set(); } return rc; }

邏輯是:如果Counter為0(非空閑),則證明已經有其他線程先一步進入當前邏輯,則當前線程需要等待5秒鐘(5秒鐘超時後繼續執行代碼),finally中的代碼表示執行完後會將Counter置為1(空閑)並喚醒其他等待的線程,讓其他線程在超時之前繼續執行。

相關代碼解釋:

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的原始值。

.net core WebApi並發同步