Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不执行方法的情况下释放锁_C#_Wcf_Locking - Fatal编程技术网

C# 在不执行方法的情况下释放锁

C# 在不执行方法的情况下释放锁,c#,wcf,locking,C#,Wcf,Locking,我正在使用的系统由一个承载各种WCF服务的Windows服务组成。多个客户端可以与同一服务通话,但一次只能有一个客户端与一个服务通话。 因此,我使用“lock()”来防止多个客户端发生冲突。如果Client1向服务发出第一个请求,然后Client2在前者仍在执行时发出另一个请求,则“锁”会将该第二个请求保持到第一个请求完成为止 到目前为止还不错。现在的问题是我必须处理事件(我不认为简单的回调就可以解决问题)。 换句话说,当第一个请求正在运行时,客户端2可能需要知道一些事情。 当这种情况发生时,C

我正在使用的系统由一个承载各种WCF服务的Windows服务组成。多个客户端可以与同一服务通话,但一次只能有一个客户端与一个服务通话。
因此,我使用“lock()”来防止多个客户端发生冲突。如果Client1向服务发出第一个请求,然后Client2在前者仍在执行时发出另一个请求,则“锁”会将该第二个请求保持到第一个请求完成为止

到目前为止还不错。现在的问题是我必须处理事件(我不认为简单的回调就可以解决问题)。
换句话说,当第一个请求正在运行时,客户端2可能需要知道一些事情。
当这种情况发生时,Client2将收到该事件,并最终停止使用该服务。
这里的问题是我们的第二个请求已经在储物柜的队列中。
那么我如何防止第二个请求运行呢。它会被取消吗?
也许这只是增加一面脏旗的问题,但我希望有更好的方法来做到这一点。
下面是在服务端显示脏标志“canRun”的样子:


如果您可以切换到
async
/
wait
和类似于
信号量lim
的东西,那么:
取消令牌
就是您要找的;
CancellationTokenSource
可以随时标记为已取消,代码可以相应地响应,并且大多数框架/库代码已经正确地处理了取消,例如:在异步信号量获取期间

如果您需要保持同步,那么您最好的选择可能是切换到循环
监视器
模式,该模式可以重新检查每个超时,例如:

bool locktake=false;
尝试
{
做
{
如果(!canRun)抛出新操作CanceledException();
监视器.TryEnter(_locker,someTimeout,ref locktake);
}
而(!锁定);
//现在我们有海螺了
somethod();
}
最后
{
如果(锁定)监视器退出(锁定);
}

请注意,如果
canRun
是一个字段,您需要确保它是
易失性的
,或者以其他方式适当访问,以避免被缓存在寄存器或类似文件中。

取消进程的首选方法是使用
CancellationToken
。然而,您应该扩展您的示例,使您的用例更加清晰。我看不出事件是如何在这里起作用的。谢谢@PMF,这是因为客户实际上需要知道发生了什么,但我认为它不会负责根据该事件取消请求(可能不可能)?或者这就是CancellationToken的意义所在?谁能触发取消取决于您的实现。如上所述,您需要提供更多的上下文。我认为您也可以将服务设置为单线程:谢谢@Ding Peng,但我确实需要将ConcurrencyMode设置为Multiple,因为在您的示例中,
Locktake
从未更新过。而且,这会导致忙等待。@PMF糟糕,我错过了
ref
!固定的;这不是一个热循环;是的,它比问题中的代码更忙,但它不会坐在CPU上等待答案。这是惯例吗?如果我在每个API的方法中添加这些代码,它将变得非常繁忙。@stackMeUp我想说的是,这种情况并不常见,至少在
lock
;我同意,这是混乱的;
CancellationToken
会更方便,但这不适用于
lock
/
Monitor
好的,我将探索CancellationToken选项,看看是否可以使用它:-)
lock (_locker)
{ 
    if (canRun)
       return SomeMethod();
    else
       return null;
}