我想知道如何实现以下限制:在早期调用完成之前,不应再次调用Windows服务中的一种方法。有问题的方法通过几个数据库表进行,非常重要的是在完成之前不会再次调用此过程。我有一个设置,定义我的服务将激活的频率,在正常情况下,它永远不会在早期调用完成之前激活(因为整个过程不应超过几分钟,间隔设置为10分钟)但不是果然。我想。
如何实现这个?
答案 0 :(得分:12)
您可以使用named Mutex或named Semaphor e来确保只有一个Mutex / Semaphore的持有者一次执行。正如评论者指出的那样,请记住,您必须小心不要放弃互斥锁或不正确地获取/释放信号量。
答案 1 :(得分:5)
一种方法是使用锁定:
private readonly object myLock = new object();
private void MyMethod()
{
lock(myLock)
{
//code goes here
}
}
这可确保此方法永远不会再运行一次。
答案 2 :(得分:2)
我是Mutex的第二个建议,但您可能还想看看交易。将整个代码包装在一个事务中(这需要using System.Transactions
):
using(TransactionScope scope = new TransactionScope())
{
try
{
/* ... your current code here */
scope.Complete();
}
catch (Exception e)
{
/* Any appropriate error handling/logging here */
}
finally
{
}
}
transactioncope会自动锁定所有相关表。您可以减少限制并允许其他进程读取,但不能写入您的进程正在触摸的数据。您可以通过将选项传递给TransactionsScope构造函数来完成此操作。
答案 3 :(得分:1)
如果所有代码都已本地化,您可以设置布尔值并在执行方法之前检查布尔值,否则您可以在执行之前IPC并请求状态。
答案 4 :(得分:1)
一些替代方案:
我确定还有其他人。
答案 5 :(得分:0)
这听起来像是一个串行工作流......您是否考虑过使用工作流框架?
答案 6 :(得分:0)
如果您不介意一次将一个线程限制为整个对象,则可以使用:
CLR一次只允许一个线程为每个类的实例执行代码。其他人将阻塞,直到当前线程释放锁定。
答案 7 :(得分:0)
如果您希望使用await / async
运行函数private static readonly SemaphoreSlim yourLock = new SemaphoreSlim(1, 1); //allow only 1 thread at time
...
private async Task<string> YourFunction() {
await yourLock.WaitAsync();
try
{
//your code go here
}
finally
{
yourLock.Release();
}
}