锁定异步任务C#

csn*_*910 5 c# asynchronous locking

public class MyDbContext : DbContext
{
    ....

    static readonly object lockObject = new object();

    public override int SaveChanges()
    {
        lock (lockObject)
            return base.SaveChanges();
    }

    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        lock (lockObject)
            return base.SaveChangesAsync(cancellationToken);
    }       
}
Run Code Online (Sandbox Code Playgroud)

我想在多个线程中使用DbContext,但是如果两个线程同时写入,则基础数据库有问题。所以我使用lockObject来防止同时出现两个SaveChanges()。

在SaveChanges()中可以正常工作,但是我不知道如何在SaveChangesAsync()中执行相同的操作。我认为上述解决方案是错误的。如何将锁应用于SaveChangesAsync?

谢谢!

Ive*_*Ive 6

https://blog.cdemi.io/async-waiting-inside-c-sharp-locks/ 您可以使用:

public class MyDbContext 
{
    static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);

    public override int SaveChanges()
    {
        semaphoreSlim.Wait();
        try
        {
            return base.SaveChanges();
        }
        finally
        {
            //When the task is ready, release the semaphore. It is vital to ALWAYS release the semaphore when we are ready, or else we will end up with a Semaphore that is forever locked.
            //This is why it is important to do the Release within a try...finally clause; program execution may crash or take a different path, this way you are guaranteed execution
            semaphoreSlim.Release();
        }
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        await semaphoreSlim.WaitAsync(cancellationToken);
        try
        {
            return await base.SaveChangesAsync();
        }
        finally
        {
            //When the task is ready, release the semaphore. It is vital to ALWAYS release the semaphore when we are ready, or else we will end up with a Semaphore that is forever locked.
            //This is why it is important to do the Release within a try...finally clause; program execution may crash or take a different path, this way you are guaranteed execution
            semaphoreSlim.Release();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)