0

I have a process that runs every two min and execute the method.

Sometimes, the process takes more than two min. In this case, I want the process to wait until the process is completed.

My code looks as below. I tried lock, monitor but none working because of async-await. I am getting this error SynchronizationLockException on Monitor.Exit when using await

public async Task RunProcess()
{
   await GetRecords();
   await CheckDuplicates();
   await InsertRecords();
}

What is the best practice to implement this?

Chatra
  • 2,989
  • 7
  • 40
  • 73
  • Make sure method you are calling are async as well – Wasim Jul 31 '20 at 13:34
  • 1
    Also [this answer](https://stackoverflow.com/a/27231538/2957232) – Code Stranger Jul 31 '20 at 13:37
  • If this process runs once every few minutes, why use async at all? Go full sync abd then the lock will work. If this process is en exe using monitor will not help, since it its scope is process wide – Menahem Jul 31 '20 at 13:42
  • @BrootsWaymb I don't understand that answer at all – Chatra Jul 31 '20 at 14:04
  • @Chatra - which part? Did you look into the [SemaphoreSlim](https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-3.1) class that the top answer mentioned? – Broots Waymb Jul 31 '20 at 14:10
  • @BrootsWaymb So the answer is SemaphoreSlim not monitor and lock ? – Chatra Jul 31 '20 at 14:20
  • @Chatra ..yes. that's what the last paragraph of the accepted is answer saying. – Broots Waymb Jul 31 '20 at 14:22
  • @BrootsWaymb In that answer new SemphoreSlim(1). what is 1? MSDB says differently SemaphoreSlim(0,3) https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netframework-4.7 – Chatra Jul 31 '20 at 15:01
  • Have you tried to just `await` the `RunProcess`? – Theodor Zoulias Jul 31 '20 at 15:50
  • @Chatra - that's just example code... there are multiple options for [constructors](https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim.-ctor?view=netframework-4.7) and which value to use is completely up to you. In `SemaphoreSlim(1)`, that 1 corresponds to "The initial number of requests for the semaphore that can be granted concurrently". – Broots Waymb Jul 31 '20 at 17:19

1 Answers1

4

SemaphoreSlim is an async-compatible mutual exclusion primitive (i.e., "lock"):

private SemaphoreSlim _processLock = new SemaphoreSlim(1);
public async Task RunProcess()
{
  await _processLock.WaitAsync();
  try
  {
    await GetRecords();
    await CheckDuplicates();
    await InsertRecords();
  }
  finally
  {
    _processLock.Release();
  }
}
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810