我有一个帮助函数,它将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