From db215dc033392d843cec846f0a8f9dbff2578c6a Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期四, 04 十二月 2025 12:57:53 +0800
Subject: [PATCH] 提交
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs | 405 ++++++++++++++++++++++++++++++---------------------------
1 files changed, 212 insertions(+), 193 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
index 4590d03..15db4f7 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
@@ -5,6 +5,7 @@
using Org.BouncyCastle.Asn1.Ocsp;
using SqlSugar;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
@@ -28,30 +29,6 @@
namespace WIDESEA_BasicService
{
- public class TransferDataDto
- {
- public DateTime TransferTime { get; set; }
- public List<TransferItemDto> Items { get; set; }
- }
-
- public class TransferItemDto
- {
- public string MaterialCode { get; set; }
- public decimal TotalQuantity { get; set; }
- public List<LocationInfoDto> Locations { get; set; }
- }
- public class LocationInfoDto
- {
- public string LocationCode { get; set; }
- public decimal Quantity { get; set; }
- public List<BarcodeInfoDto> Barcodes { get; set; }
- }
-
- public class BarcodeInfoDto
- {
- public string Barcode { get; set; }
- public decimal Quantity { get; set; }
- }
public class InvokeMESService : IInvokeMESService
{
private readonly IHttpClientFactory _httpClientFactory;
@@ -68,6 +45,12 @@
private readonly IOutboundOrderService _outboundOrderService;
private readonly IOutboundOrderDetailService _outboundOrderDetailService;
private readonly IOutStockLockInfoService _outStockLockInfoService;
+
+ // 瀛樺偍璧勬簮ID鍙婂叾瀵瑰簲鐨勯攣瀵硅薄銆備娇鐢� ConcurrentDictionary 纭繚瀵瑰瓧鍏告搷浣滄湰韬殑绾跨▼瀹夊叏銆�
+ private static readonly ConcurrentDictionary<string, object> _resourceLocks = new ConcurrentDictionary<string, object>();
+
+ // 鍏ㄥ眬闈欐�侀攣锛氱敤浜庝繚鎶� _resourceLocks 瀛楀吀涓� GetOrAdd 鎴� TryRemove 鏃剁殑绔炰簤
+ private static readonly object _globalLocker = new object();
public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IOutStockLockInfoService outStockLockInfoService, IMaterialUnitService materialUnitService, IRepository<Dt_PickingRecord> pickingRecoreRepository)
{
_httpClientFactory = httpClientFactory;
@@ -129,7 +112,7 @@
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("Accept", "application/json");
- _logger.LogInformation("InvokeMESService FeedbackOutbound : " + json);
+ _logger.LogInformation("InvokeMESService FeedbackOutbound : " + model.orderNo + " , " + json);
var response = await _client.PostAsync("AldMaterialOutbound/MaterialOutbound", content);
string body = await response.Content.ReadAsStringAsync();
@@ -139,7 +122,7 @@
throw new HttpRequestException(body);
}
-
+ _logger.LogInformation("InvokeMESService FeedbackOutbound body: " + body);
return JsonConvert.DeserializeObject<ResponseModel>(body);
}
@@ -248,57 +231,7 @@
}
}
- /// <summary>
- /// 鍑嗗鍥炰紶鏁版嵁
- /// </summary>
- private TransferDataDto PrepareTransferData(List<Dt_PickingRecord> pickingRecords)
- {
- var transferData = new TransferDataDto
- {
- TransferTime = DateTime.Now,
- Items = new List<TransferItemDto>()
- };
- // 鎸夌墿鏂欏垎缁�
- var materialGroups = pickingRecords
- .GroupBy(x => x.MaterielCode)
- .ToList();
-
- foreach (var group in materialGroups)
- {
- var item = new TransferItemDto
- {
- MaterialCode = group.Key,
- TotalQuantity = group.Sum(x => x.PickQuantity),
- Locations = new List<LocationInfoDto>()
- };
-
- // 鎸夎揣浣嶅垎缁�
- var locationGroups = group
- .GroupBy(x => x.LocationCode)
- .ToList();
-
- foreach (var locationGroup in locationGroups)
- {
- var location = new LocationInfoDto
- {
- LocationCode = locationGroup.Key,
- Quantity = locationGroup.Sum(x => x.PickQuantity),
- Barcodes = locationGroup.Select(x => new BarcodeInfoDto
- {
- Barcode = x.Barcode,
- Quantity = x.PickQuantity
- }).ToList()
- };
-
- item.Locations.Add(location);
- }
-
- transferData.Items.Add(item);
- }
-
- return transferData;
- }
/// <summary>
///
@@ -308,141 +241,159 @@
/// <returns></returns>
public async Task<WebResponseContent> BatchOrderFeedbackToMes(List<string> orderNos, int inout)
{
- if (inout == 1)
+ // 1. 銆愬唴瀛橀攣鎶㈠崰銆�
+ if (MemoryLockManager.TryAcquireLock(orderNos[0]))
{
- foreach (var orderNo in orderNos)
+ try
{
- try
+ if (inout == 1)
{
- var stockinfos = _stockInfoRepository.Db.Queryable<Dt_StockInfo>("info").Where(info => info.StockStatus == 6)
- .Where(it => SqlFunc.Subqueryable<Dt_StockInfoDetail>().Where(s => s.StockId == it.Id && s.OrderNo == orderNo).Any())
- .ToList();
- var feeds = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList();
- var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList();
- if (unreports != null && !unreports.Any())
+ foreach (var orderNo in orderNos)
{
- return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖浼犵殑鏁版嵁");
- }
- foreach (var item in unreports)
- {
- var lists = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.StockId == item.Id).ToList();
- if (lists.Any())
+ try
{
- var inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().First(x => x.InboundOrderNo == lists.FirstOrDefault().OrderNo);
- if (inboundOrder != null)
+ var stockinfos = _stockInfoRepository.Db.Queryable<Dt_StockInfo>("info").Where(info => info.StockStatus == 6)
+ .Where(it => SqlFunc.Subqueryable<Dt_StockInfoDetail>().Where(s => s.StockId == it.Id && s.OrderNo == orderNo).Any())
+ .ToList();
+ var feeds = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList();
+ var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList();
+ if (unreports != null && !unreports.Any())
{
- if (inboundOrder.OrderType == (int)InOrderTypeEnum.AllocatInbound)//璋冩嫧鍏ュ簱
+ return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖浼犵殑鏁版嵁");
+ }
+ foreach (var item in unreports)
+ {
+ var lists = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.StockId == item.Id).ToList();
+ if (lists.Any())
{
- var allocate = SqlSugarHelper.DbWMS.Queryable<Dt_AllocateOrder>().Where(x => x.OrderNo == inboundOrder.InboundOrderNo).First();
- var allocatefeedmodel = new AllocateDto
+ var inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().First(x => x.InboundOrderNo == lists.FirstOrDefault().OrderNo);
+ if (inboundOrder != null)
{
- ReqCode = Guid.NewGuid().ToString(),
- ReqTime = DateTime.Now.ToString(),
- BusinessType = "2",
- FactoryArea = inboundOrder.FactoryArea,
- OperationType = 1,
- Operator = inboundOrder.Operator,
- OrderNo = inboundOrder.UpperOrderNo,
- fromWarehouse = allocate?.FromWarehouse ?? "",
- toWarehouse = allocate?.ToWarehouse ?? "",
- Details = new List<AllocateDtoDetail>()
+ if (inboundOrder.OrderType == (int)InOrderTypeEnum.AllocatInbound)//璋冩嫧鍏ュ簱
+ {
+ var allocate = SqlSugarHelper.DbWMS.Queryable<Dt_AllocateOrder>().Where(x => x.OrderNo == inboundOrder.InboundOrderNo).First();
+ var allocatefeedmodel = new AllocateDto
+ {
+ ReqCode = Guid.NewGuid().ToString(),
+ ReqTime = DateTime.Now.ToString(),
+ BusinessType = "2",
+ FactoryArea = inboundOrder.FactoryArea,
+ OperationType = 1,
+ Operator = inboundOrder.Operator,
+ OrderNo = inboundOrder.UpperOrderNo,
+ fromWarehouse = allocate?.FromWarehouse ?? "",
+ toWarehouse = allocate?.ToWarehouse ?? "",
+ Details = new List<AllocateDtoDetail>()
- };
+ };
- var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
- .Select(group => new AllocateDtoDetail
- {
- MaterialCode = group.Key.MaterielCode,
- LineNo = group.Key.InboundOrderRowNo,
- WarehouseCode = group.Key.WarehouseCode,
- Qty = group.Sum(x => x.BarcodeQty),
- Unit = group.Key.BarcodeUnit,
- Barcodes = group.Select(row => new BarcodeInfo
- {
- Barcode = row.Barcode,
- Qty = row.BarcodeQty,
- BatchNo = row.BatchNo,
- SupplyCode = row.SupplyCode,
- Unit = row.BarcodeUnit
- }).ToList()
- }).ToList();
- allocatefeedmodel.Details = groupedData;
+ var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
+ .Select(group => new AllocateDtoDetail
+ {
+ MaterialCode = group.Key.MaterielCode,
+ LineNo = group.Key.InboundOrderRowNo,
+ WarehouseCode = group.Key.WarehouseCode,
+ Qty = group.Sum(x => x.BarcodeQty),
+ Unit = group.Key.BarcodeUnit,
+ Barcodes = group.Select(row => new BarcodeInfo
+ {
+ Barcode = row.Barcode,
+ Qty = row.BarcodeQty,
+ BatchNo = row.BatchNo,
+ SupplyCode = row.SupplyCode,
+ Unit = row.BarcodeUnit
+ }).ToList()
+ }).ToList();
+ allocatefeedmodel.Details = groupedData;
- var result = await FeedbackAllocate(allocatefeedmodel);
- if (result != null && result.code == 200)
- {
- _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
- }
- }
- else
- {
- var feedmodel = new FeedbackInboundRequestModel
- {
- reqCode = Guid.NewGuid().ToString(),
- reqTime = DateTime.Now.ToString(),
- business_type = inboundOrder.BusinessType,
- factoryArea = inboundOrder.FactoryArea,
- operationType = 1,
- Operator = inboundOrder.Operator,
- orderNo = inboundOrder.UpperOrderNo,
- status = inboundOrder.OrderStatus,
- details = new List<FeedbackInboundDetailsModel>()
+ var result = await FeedbackAllocate(allocatefeedmodel);
+ if (result != null && result.code == 200)
+ {
+ _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
+ }
+ }
+ else
+ {
+ var feedmodel = new FeedbackInboundRequestModel
+ {
+ reqCode = Guid.NewGuid().ToString(),
+ reqTime = DateTime.Now.ToString(),
+ business_type = inboundOrder.BusinessType,
+ factoryArea = inboundOrder.FactoryArea,
+ operationType = 1,
+ Operator = inboundOrder.Operator,
+ orderNo = inboundOrder.UpperOrderNo,
+ status = inboundOrder.OrderStatus,
+ details = new List<FeedbackInboundDetailsModel>()
- };
+ };
- var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
- .Select(group => new FeedbackInboundDetailsModel
- {
- materialCode = group.Key.MaterielCode,
- supplyCode = group.Key.SupplyCode,
- batchNo = group.Key.BatchNo,
- lineNo = group.Key.InboundOrderRowNo,
- qty = group.Sum(x => x.BarcodeQty),
- // warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
- warehouseCode = group.Key.WarehouseCode,
- unit = group.Key.BarcodeUnit,
- barcodes = group.Select(row => new FeedbackBarcodesModel
- {
- barcode = row.Barcode,
- qty = row.BarcodeQty
- }).ToList()
- }).ToList();
- feedmodel.details = groupedData;
- var result = await FeedbackInbound(feedmodel);
- if (result != null && result.code == 200)
- {
- _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
+ var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
+ .Select(group => new FeedbackInboundDetailsModel
+ {
+ materialCode = group.Key.MaterielCode,
+ supplyCode = group.Key.SupplyCode,
+ batchNo = group.Key.BatchNo,
+ lineNo = group.Key.InboundOrderRowNo,
+ qty = group.Sum(x => x.BarcodeQty),
+ // warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
+ warehouseCode = group.Key.WarehouseCode,
+ unit = group.Key.BarcodeUnit,
+ barcodes = group.Select(row => new FeedbackBarcodesModel
+ {
+ barcode = row.Barcode,
+ qty = row.BarcodeQty
+ }).ToList()
+ }).ToList();
+ feedmodel.details = groupedData;
+ var result = await FeedbackInbound(feedmodel);
+ if (result != null && result.code == 200)
+ {
+ _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
+ }
+ }
}
}
}
}
+ catch (Exception ex)
+ {
+ _logger.LogInformation("InvokeMESService BatchOrderFeedbackToMes 鍥炲啓MES澶辫触: " + ex.Message);
+ return WebResponseContent.Instance.Error(ex.Message);
+ }
+
}
}
- catch (Exception ex)
+ else if (inout == 2)
{
- _logger.LogInformation("InvokeMESService BatchOrderFeedbackToMes 鍥炲啓MES澶辫触: " + ex.Message);
- return WebResponseContent.Instance.Error(ex.Message);
- }
+ foreach (var orderNo in orderNos)
+ {
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo);
+ if (outboundOrder != null && outboundOrder.IsBatch == 0)
+ {
+ var result = await HandleOutboundOrderToMESCompletion(outboundOrder, orderNo);
+ return result;
+ }
+ else if (outboundOrder != null && outboundOrder.IsBatch == 1)
+ {
+ var result = await HandleOutboundOrderBatchToMESCompletion(outboundOrder, orderNo);
+ return result;
+ }
+ }
+ }
+ }
+ finally
+ {
+ // 2. 銆愰噴鏀惧唴瀛橀攣銆戞棤璁烘垚鍔熷け璐ワ紝蹇呴』閲婃斁
+ MemoryLockManager.ReleaseLock(orderNos[0]);
}
}
- else if (inout == 2)
+ else
{
- foreach (var orderNo in orderNos)
- {
- var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo);
- if (outboundOrder != null && outboundOrder.IsBatch == 0)
- {
- var result = await HandleOutboundOrderToMESCompletion(outboundOrder, orderNo);
- return result;
- }
- else if (outboundOrder != null && outboundOrder.IsBatch == 1)
- {
- var result = await HandleOutboundOrderBatchToMESCompletion(outboundOrder, orderNo);
- return result;
- }
- }
+ // 鎶㈤攣澶辫触锛氳鏄庢湁鍙︿竴涓嚎绋嬶紙WCS鍥炶皟鎴栦汉宸ユ搷浣滐級姝e湪澶勭悊
+ return WebResponseContent.Instance.OK("WMS姝e湪澶勭悊姝ゅ洖浼犱换鍔★紝璇峰嬁閲嶅鎿嶄綔銆�");
}
return WebResponseContent.Instance.OK();
}
@@ -489,7 +440,7 @@
business_type = outboundOrder.BusinessType,
factoryArea = outboundOrder.FactoryArea,
operationType = 1,
- Operator = outboundOrder.Operator!=""? outboundOrder.Operator:App.User.UserName,
+ Operator = outboundOrder.Operator != "" ? outboundOrder.Operator : App.User.UserName,
orderNo = outboundOrder.UpperOrderNo,
documentsNO = documentNo,
status = outboundOrder.OrderStatus,
@@ -511,7 +462,7 @@
materialCode = detail.MaterielCode,
lineNo = detail.lineNo,
warehouseCode = detail.WarehouseCode,
- qty = 0,
+ qty = detail.BarcodeQty,
currentDeliveryQty = 0,
unit = detail.BarcodeUnit,
barcodes = new List<WIDESEA_DTO.Outbound.BarcodesModel>()
@@ -545,7 +496,6 @@
{
barModel.qty = item.PickQuantity;
}
- detailModel.qty += barModel.qty;
detailModel.currentDeliveryQty += barModel.qty;
detailModel.barcodes.Add(barModel);
}
@@ -553,12 +503,12 @@
feedModel.details.Add(detailModel);
}
- feedModel.details = feedModel.details.GroupBy(item => new { item.materialCode, item.lineNo, item.warehouseCode, item.unit }).Select(group => new FeedbackOutboundDetailsModel
+ feedModel.details = feedModel.details.GroupBy(item => new { item.materialCode, item.lineNo, item.warehouseCode, item.unit, item.qty }).Select(group => new FeedbackOutboundDetailsModel
{
materialCode = group.Key.materialCode,
lineNo = group.Key.lineNo,
warehouseCode = group.Key.warehouseCode,
- qty = group.Sum(x => x.qty),
+ qty = group.Key.qty,
currentDeliveryQty = group.Sum(x => x.currentDeliveryQty),
unit = group.Key.unit,
barcodes = group.SelectMany(x => x.barcodes.GroupBy(o => new { o.barcode, o.supplyCode, o.batchNo, o.unit }).Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
@@ -829,6 +779,11 @@
.Where(x => x.OrderNo == orderNo)
.ExecuteCommandAsync();
+ await _pickingRecoreRepository.Db.Updateable<Dt_PickingRecord>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
return WebResponseContent.Instance.OK("鍥炰紶MES鎴愬姛");
}
else
@@ -862,14 +817,78 @@
public static string Generate()
{
var now = DateTime.Now;
- string datePart = now.ToString("yyyyMMdd");
+ string datePart = now.ToString("MMdd");
long ticksPart = now.Ticks;
+ // 鎷兼帴锛氳鏁板櫒琛�0涓�3浣嶏紙閬垮厤浣嶆暟涓嶄竴鑷达級
+ return $"{datePart}{ticksPart}";
+ }
+
+ public static string GenerateCount()
+ {
+ var now = DateTime.Now;
+ string datePart = now.ToString("yyyyMMddHHmmss");
+
// 鍘熷瓙閫掑璁℃暟鍣紙鍙栨ā1000锛岀‘淇濊鏁板櫒浠�3浣嶏紝鎺у埗闀垮害锛�
long counterPart = Interlocked.Increment(ref _counter) % 1000;
// 鎷兼帴锛氳鏁板櫒琛�0涓�3浣嶏紙閬垮厤浣嶆暟涓嶄竴鑷达級
- return $"{datePart}{ticksPart}{counterPart:D3}";
+ return $"{datePart}{counterPart:D3}";
+ }
+ }
+
+
+ public static class MemoryLockManager
+ {
+ // 瀛樺偍璧勬簮ID鍙婂叾瀵瑰簲鐨勯攣瀵硅薄銆備娇鐢� ConcurrentDictionary 纭繚瀵瑰瓧鍏告搷浣滄湰韬殑绾跨▼瀹夊叏銆�
+ private static readonly ConcurrentDictionary<string, object> _resourceLocks = new ConcurrentDictionary<string, object>();
+
+ // 鍏ㄥ眬闈欐�侀攣锛氱敤浜庝繚鎶� _resourceLocks 瀛楀吀涓� GetOrAdd 鎴� TryRemove 鏃剁殑绔炰簤
+ private static readonly object _globalLocker = new object();
+
+ /// <summary>
+ /// 灏濊瘯閿佸畾涓�涓祫婧怚D銆�
+ /// </summary>
+ /// <param name="resourceId">瑕侀攣瀹氱殑璧勬簮ID锛堜緥濡� InboundRecord ID锛�</param>
+ /// <returns>鏄惁鎴愬姛鑾峰彇閿�</returns>
+ public static bool TryAcquireLock(string resourceId)
+ {
+ object lockObject = null;
+
+ // 鏍稿績鎬濊矾锛氫负姣忎釜璧勬簮鍒涘缓涓�涓敮涓�鐨勯攣瀵硅薄
+ lock (_globalLocker)
+ {
+ // 濡傛灉璧勬簮ID涓嶅湪瀛楀吀涓紝鍒欐坊鍔犱竴涓柊鐨勯攣瀵硅薄
+ // 鍚﹀垯锛屼娇鐢ㄥ凡瀛樺湪鐨勯攣瀵硅薄
+ lockObject = _resourceLocks.GetOrAdd(resourceId, new object());
+ }
+
+ // 灏濊瘯鑾峰彇璧勬簮鐗瑰畾鐨勯攣
+ // 浣跨敤 Monitor.TryEnter 閬垮厤闃诲锛屽苟瀹炵幇闈為樆濉炵殑鎶㈤攣
+ return Monitor.TryEnter(lockObject);
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮ID鐨勯攣瀹氥��
+ /// </summary>
+ /// <param name="resourceId">瑕侀噴鏀剧殑璧勬簮ID</param>
+ public static void ReleaseLock(string resourceId)
+ {
+ if (_resourceLocks.TryGetValue(resourceId, out object lockObject))
+ {
+ // 纭繚閲婃斁鐨勬槸褰撳墠绾跨▼鎸佹湁鐨勯攣
+ if (Monitor.IsEntered(lockObject))
+ {
+ Monitor.Exit(lockObject);
+
+ // 閲婃斁閿佸悗锛屽皾璇曚粠瀛楀吀涓Щ闄よ繖涓攣瀵硅薄锛屾竻鐞嗗唴瀛樸��
+ // 蹇呴』鍦� Monitor.Exit 涔嬪悗鎵ц銆�
+ lock (_globalLocker)
+ {
+ _resourceLocks.TryRemove(resourceId, out _);
+ }
+ }
+ }
}
}
}
--
Gitblit v1.9.3