我需要尝试锁定一个对象,如果它已经锁定只是继续(超时后,或没有它).
C#lock语句是阻塞的.
我正在研究各种消费者使用的C#API.此API提供对共享资源的访问(在我的情况下是执行串行通信的硬件),通常会有一些不同的参与者尝试同时使用它.
我遇到的问题是我的一些消费者希望在多线程环境中使用它 - 每个actor都独立工作并尝试使用该资源.一个简单的锁在这里工作正常.但我的一些消费者更愿意使用async-await和时间片资源.(据我所知),这需要一个异步锁定来将时间片返回到其他任务; 在锁定时阻塞会停止整个线程.
而且我认为拥有串行锁定最多是无法执行的,并且最坏的情况是潜在的竞争条件或死锁.
那么如何在公共代码库中为潜在的并发使用保护这个共享资源呢?
我想在缓存中放置一个身份验证令牌,可以在多个应用程序域中使用它.此令牌将每小时到期.当客户端无法使用令牌进行授权时,它会要求令牌生成服务生成新令牌.
我只希望第一个不成功进行身份验证的客户端进行此重新生成,因此我使用了这样的锁定对象:
public async Task<Token> GenerateToken(Token oldToken)
{
Token token;
lock (lockObject)
{
var cachedToken = GetTokenFromCache();
if (cachedToken == oldToken)
{
var authClient = new AuthClient(id, key);
token = await authClient.AuthenticateClientAsync(); //KABOOM
PutTokenInCache(token);
}
else
{
token = cachedToken;
}
}
return token;
}
Run Code Online (Sandbox Code Playgroud)
我的问题AuthClient只有async方法,而且async在lock-statement块中不允许使用方法.我没有任何控制权AuthClient,我可以在这里使用其他策略吗?
我正在从我的数据库加载一些值以显示给我的网站用户。由于这些值不会改变太多,我将它们加载到静态/共享对象中。
为了确保多个用户不会同时修改同一个对象,我使用Monitor.Enter(和Monitor.Exit) 来锁定/阻止这些值的加载。
不幸的是,这在从 .NET 中的 MVC 视图调用时不起作用,因为它会引发此异常:
从未同步的代码块调用对象同步方法。
有没有办法通过 MVC 做到这一点,而无需完全改变我的代码设计?