Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

549
Views
Alternatives for Monitor (Wait, PluseAll) in Async Tasks in C#

I implemented Task synchronization using Monitor in C#. However, I have read Monitor should not be used in asynchronous operation.

In the below code, how do I implement Monitor methods Wait and PulseAll with a construct that works with Task (asynchronous operations).

I have read that SemaphoreSlim.WaitAsync and Release methods can help. But how do they fit in the below sample where multiple tasks need to wait on a lock object, and releasing the lock wakes up all waiting tasks ?

private bool m_condition = false;
private readonly Object m_lock = new Object();

private async Task<bool> SyncInteralWithPoolingAsync(            
            SyncDatabase db,
            List<EntryUpdateInfo> updateList)
{           
        List<Task> activeTasks = new List<Task>();

        int addedTasks = 0;
        int removedTasks = 0;
    
        foreach (EntryUpdateInfo entryUpdateInfo in updateList)
        {            
            Monitor.Enter(m_lock);              
    
            //If 5 tasks are waiting in ProcessEntryAsync method                
            if(m_count >= 5)
            {                   
                //Do some batch processing to obtian values to set for adapterEntry.AdapterEntryId in ProcessEntryAsync
                //.......
                //.......
                
                m_condition = true;                 
                Monitor.PulseAll(m_lock); // Wakes all waiters AFTER lock is released                                           
            }               
    
            Monitor.Exit(m_lock);
            
            removedTasks += activeTasks.RemoveAll(t => t.IsCompleted);

            Task processingTask = Task.Run(
                    async () =>
                    {
                        await this.ProcessEntryAsync(
                                entryUpdateInfo,
                                db)
                            .ContinueWith(this.ProcessEntryCompleteAsync)
                            .ConfigureAwait(false);
                    });

            activeTasks.Add(processingTask);
            addedTasks++;              
       }           
}                   
            


private async Task<bool> ProcessEntryAsync(SyncDatabase db, EntryUpdateInfo entryUpdateInfo)
{
      SyncEntryAdapterData adapterEntry = 
         updateInfo.Entry.AdapterEntries.FirstOrDefault(e => e.AdapterId == this.Config.Id);

      if (adapterEntry == null)
      {
          adapterEntry = new SyncEntryAdapterData()
          {
               SyncEntry = updateInfo.Entry,
               AdapterId = this.Config.Id
          };

          updateInfo.Entry.AdapterEntries.Add(adapterEntry);
       }

       m_condition = false;
       Monitor.Enter(m_lock);           
       while (!m_condition)
       {
          m_count++;
          Monitor.Wait(m_lock); 
       }
  
       m_count--;
       adapterEntry.AdapterEntryId =  .... //Set Value obtained form batch processing
       
       Monitor.Exit(m_lock);
}

private void ProcessEntryCompleteAsync(Task<bool> task, object context)
{
        EntryProcessingContext ctx = (EntryProcessingContext)context;

        try
        {
            string message;
            if (task.IsCanceled)
            {
                Logger.Warning("Processing was cancelled");                  
                message = "The change was cancelled during processing";
            }
            else if (task.Exception != null)
            {
                Exception ex = task.Exception;                 
                Logger.Warning("Processing failed with {0}: {1}", ex.GetType().FullName, ex.Message);
                message = "An error occurred while synchronzing the changed.";
            }
            else
            {
                message = "The change was successfully synchronized";

                if (task.Result)
                {
                   //Processing
                   //...
                   //...
                }
            }
        }
        catch (Exception e)
        {
            Logger.Info(
                "Caught an exception while completing entry processing. " + e);
        }
        finally
        {
        }
 }

Thanks

over 4 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!