Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

540
Vistas
Alternativas para Monitor (Wait, PluseAll) en tareas asíncronas en C#

Implementé la sincronización de tareas usando Monitor en C#. Sin embargo, he leído que Monitor no debe usarse en operación asincrónica.

En el siguiente código, ¿cómo implemento los métodos Monitor Wait y PulseAll con una construcción que funciona con Task (operaciones asíncronas)?

He leído que los métodos SemaphoreSlim.WaitAsync y Release pueden ayudar. Pero, ¿cómo encajan en el ejemplo a continuación, donde varias tareas deben esperar en un objeto de bloqueo, y al liberar el bloqueo se activan todas las tareas en espera?

 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 { } }

Gracias

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda