我有一個幫助函數,它將XML文件反序列化,並從中生成c#對象。Asp.net MVC API基於方法參數鎖定函數
之後,將對象添加到服務器內存中。在服務器內存中添加內容的唯一方法是通過此功能。
public class DeserializeXmlHelper
{
public void DeserializeXml(Guid xml_Id, decimal version)
{
// heavy process here which takes about 3 seconds
}
}
此功能是由使用API方法(在Asp.net MVC API製造)不同的客戶端調用。
當調用API時,如果其他人已經使用相同的參數調用了相同的函數,我能否阻止該函數的執行?
這樣的事情,但我不知道這是否是一個好辦法。
public class DeserializeXmlHelper
{
private static readonly ConcurrentDictionary<string, object> _processes = new ConcurrentDictionary<string, object>();
public void DeserializeXml(Guid xml_Id, decimal version)
{
string processKey = string.Format("{0}_v{1}", xml_Id, version.ToString("#0.0"));
object processLocker = null;
if (_processes.TryGetValue(processKey, out processLocker) == false)
{
processLocker = new object();
_processes.TryAdd(processKey, processLocker);
}
lock (processLocker)
{
// heavy process here which takes about 3 seconds
_processes.TryRemove(processKey);
}
}
}
編輯 - 新版本
蒂姆·羅傑的答案是成功的工作。
但是,如果我只想在初始調用完成時返回,我可以做類似這樣的事情嗎? (我用ConcurrentDictionary,因爲我不知道怎麼加的鎖,但這個想法應該是相同的)
public class DeserializeXmlHelper
{
private static readonly ConcurrentDictionary<string, string> _processes = new ConcurrentDictionary<string, string>();
public void DeserializeXml(Guid xml_Id, decimal version)
{
string _processKey = string.Format("{0}_v{1}", xml_Id, version.ToString("#0.0"));
string _processValue = null;
if (_processes.TryGetValue(_processKey, out _processValue) == true)
{
// function already called with the same parameters
do
{
System.Threading.Thread.Sleep(100);
}
while(_processes.TryGetValue(_processKey, out _processValue) == true)
return;
}
try
{
_processes.TryAdd(_processKey, _processValue);
var begin = "begin process";
System.Threading.Thread.Sleep(10000);
var end = "ending process";
}
finally
{
_processes.TryRemove(_processKey, out _processValue);
}
}
}
如果參數相同,結果是否一樣? – 2013-03-06 13:36:44
是的,對於相同的參數相同的結果 – Catalin 2013-03-06 13:37:39
你可以使用緩存嗎?首先查看對象的緩存,以免每次都花費昂貴的代價?您可能會緩存來自Web API調用的整個結果。 – 2013-03-06 13:38:53