-6

How can I convert this singleton method to its equivalent with async? I am trying to write something like this: public static async Task<DbContext> DBContext.

public class ModelDB
{
    static DbContext _dbContext;
    readonly static object obj = new object();

    public static DbContext DBContext
    {
        get
        {
            lock (obj)
            {
                if (_dbContext == null)
                {
                    _dbContext = new MoviesDBEntities();
                }

                return _dbContext;
            }   
        }
    }
}
Servy
  • 202,030
  • 26
  • 332
  • 449
Zinov
  • 3,817
  • 5
  • 36
  • 70
  • 3
    eee, `lock` and `async` are completely different things from completely different concepts: asynchronous and parallel programming. – MarcinJuraszek Aug 03 '14 at 22:01
  • 5
    You don't have any asynchronous work to do. Also, a static DbContext is a generally a bad idea. – SLaks Aug 03 '14 at 22:07
  • 1
    Note, that you cannot use an EF context concurrently anyway. Probably this question is moot considering this. – usr Aug 03 '14 at 22:46
  • @usr. Can you explain me why I cannot use an EF context concurrently? – Zinov Aug 04 '14 at 12:58
  • @SLaks Can you tell me why is a bad idea to put my DBContext as a Singleton? – Zinov Aug 04 '14 at 12:58
  • @Zinov it's the other way round. By default nothing is thread-safe. You must have a good reason to believe that it is. EF does not guarantee thread-safety. – usr Aug 04 '14 at 12:59
  • 1
    @Zinov: DbContexts cannot be used concurrently, and hold a DB connection while active. You should create them locally and dispose them ASAP. – SLaks Aug 04 '14 at 13:14
  • @SLaks but there is not a performance issue while you create a new DBContext every time you want to use it? In my experience, the general idea is keeping alive just one instead of creating multiples, if you have a concurrent scenario, imagine having 1000 clients making a simple request to see the data of a grid on a webapplication and you creating 1000 instances of the same dbcontext. Can you tell me the best way, maybe recommend an article to read? – Zinov May 30 '17 at 15:41
  • @Zinov Would you rather have code that doesn't perform well, or code that just doesn't work at all? "Performance Improvements" are only *actually* performance improvements when they still work. That said, no, creating new contexts is not going to be particularly expensive. Creating 1000 contexts when you get 1000 requests is not likely to be a problem at all. – Servy May 30 '17 at 15:55
  • Stop editing your title to have something radically different from what the actual question is asking. If you have a new question that you want to ask, then ask a new question, don't change a 3 year old question to have a title that is quite different from what it's actually asking. – Servy May 31 '17 at 13:34

1 Answers1

2

You can (and probably should) still use a synchronous lock even while inside an async method unless you expect the lock to be held longer than usual (I guess new MoviesDBEntities(); shouldn't really take more than a few milliseconds).

When you actually need asynchronous locking you can use SemaphoreSlim set to 1 and call WaitAsync to wait asynchronously like this:

await _semphore.WaitAsync()
try
{
    ... use shared resource.
}
finally
{
    _semphore.Release()
}

Here's an implementation example.

Community
  • 1
  • 1
i3arnon
  • 113,022
  • 33
  • 324
  • 344