简体   繁体   English

锁定异步任务 c#

[英]Locking async task c#

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);
    }       
}

I want to use DbContext in multiple threads, but the underlying database has a problem if two threads are writing at the same time.我想在多个线程中使用 DbContext,但是如果两个线程同时写入,则底层数据库会出现问题。 So I am using lockObject to prevent two SaveChanges() at the same time.所以我使用 lockObject 来同时防止两个 SaveChanges() 。

That works fine in SaveChanges(), but I don't know how to do the same in SaveChangesAsync().这在 SaveChanges() 中工作得很好,但我不知道如何在 SaveChangesAsync() 中做同样的事情。 I think the solution above is wrong.我认为上面的解决方案是错误的。 How can I apply the lock to SaveChangesAsync?如何将锁定应用于 SaveChangesAsync?

Thank you!谢谢!

From https://blog.cdemi.io/async-waiting-inside-c-sharp-locks/ you can use: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();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM