我的ASP.NET站点中的代码不能同时由2个线程或进程运行,所以我把它放在一个锁中。这假设只有一个进程,并且由于IIS中的“最大工作进程数”设置为1,我觉得这是合理的。但是我做了一个让我惊讶的实验:
我创建了这个动作:
public void Test()
{
for (int i = 0; i < 100; i++)
{
System.IO.File.AppendAllText(@"c:\tmp\d.txt", $"a: {i}\n");
System.Threading.Thread.Sleep(1000);
}
}
并从我的浏览器调用它。然后我将a:
切换到b:
,编译它,并从另一个浏览器选项卡调用它。然后我打开了d.txt
,我看到了类似的东西:
b: 31
a: 67
b: 32
a: 68
b: 33
a: 69
显然,有2个进程同时运行,我的锁定不够。确保我的代码不能同时运行的最佳方法是什么?
答案 0 :(得分:2)
听起来你真的在寻找一个类似队列或队列的单件服务。使用常规ASP.NET WebAPI并不容易做到OOB。你可以摆弄它使它工作,但我会考虑以下之一:
InstanceContextMode = InstanceContextMode.Single
和ConcurrencyMode = ConcurrencyMode.Single
进行装饰。 WCF框架将负责为您做单独工作。您可以在Windows服务而不是IIS中托管它,这将进一步确保多个进程没有,并且您可以完全控制线程模型。答案 1 :(得分:1)
对于你在这里的情况,一种方法是使用mutex
// The key can be part of the file name -
// be careful not all characters are valid
var mut = new Mutex(true, key);
try
{
// Wait until it is safe to enter.
mut.WaitOne();
// now call your file manipulation function
Test();
}
finally
{
// Release the Mutex.
mut.ReleaseMutex();
}