Va bene per la funzione asincrona aggiornare un oggetto comune

1

Ho un paio di funzioni, ogni funzione verifica un insieme di regole e aggiorna un oggetto comune. L'oggetto comune è solo un contenitore che contiene un elenco di regole che hanno superato o fallito. Mi piacerebbe implementarlo come asincrono. C'è qualche aspetto negativo di questo approccio? Ci sono raccomandazioni? Di seguito il codice di esempio che intendo implementare.

using System.Collections.Generic;
using System.Threading.Tasks;

namespace RetailServiceCheck.Core
{
  //This is shared result
  public class Results
  {
    public List<int> FailedRules = new List<int>();

    public List<int> PassedRules = new List<int>();
  }

  //To Check the rules
  public class RuleChecker
  {
     Results ruleResult = null;
     public RuleChecker()
     {
         ruleResult=new Results();
     }

     public Results ValidateRule()
     {
         var ckr1=CheckRule1();
         var ckr2=CheckRule2();
         var ckr3=CheckRule3();
         Task.WaitAll(ckr1, ckr2, ckr3);
         return ruleResult;
     }

     private async Task CheckRule1()
     {
         //Do some rule check and if the based on rule failure or pass
         ruleResult.PassedRules.Add(1);
     }

     private async Task CheckRule2()
     {
         //Do some rule check and if the based on rule failure or pass
         ruleResult.FailedRules.Add(2);
     }

     private async Task CheckRule3()
     {
         //Do some rule check and if the based on rule failure or pass
         ruleResult.PassedRules.Add(3);
     }

    }
   }
    
posta BipinR 19.10.2018 - 15:49
fonte

2 risposte

2

Avendo aggiornato ogni metodo asincrono, un oggetto comune rischia di imbattersi in problemi di ordine threading / non deterministico con i risultati. Quindi, piuttosto che ogni metodo asincrono aggiorna un oggetto comune, ciascuno restituisce un risultato, quindi aggiorna i risultati quando tutti sono stati completati:

 public Results ValidateRule()
 {
     var ckr1=CheckRule1();
     var ckr2=CheckRule2();
     var ckr3=CheckRule3();
     Task.WaitAll(ckr1, ckr2, ckr3);
     UpdateRuleResult(ckr1.Result);
     UpdateRuleResult(ckr2.Result);
     UpdateRuleResult(ckr3.Result);
 }

 private void UpdateRuleResult((bool passed, int value))
 {
     if (passed)
     {
         ruleResult.PassedRules.Add(value);
     }
     else
     {
         ruleResult.FailedRules.Add(value);
     }
 }

 private async Task<(bool passed, int value)> CheckRule1()
 {
     //Do some rule check and if the based on rule failure or pass
     return (true, 1);
 }

 etc
    
risposta data 19.10.2018 - 16:22
fonte
0

Una grande preoccupazione per le funzioni asincrone è la gestione dello stato. Se la tua funzione richiede dati che potrebbero essere modificati da una funzione asincrona, è possibile che i tuoi dati cambino o diventino obsoleti prima o a metà dell'esecuzione, causando risultati imprevisti che possono essere difficili da eseguire il debug.

Se puoi impostare le tue funzioni in modo che prendano dati che non verranno modificati come input e che ciascuno di essi salvi in un diverso insieme di campi univoci (una regola diversa nel tuo caso), potresti essere in grado di evitare questo effetto collaterale con codice asincrono e farlo funzionare.

In caso contrario, devi configurare cose come il blocco per far funzionare tutto e potresti ancora incontrare bug di stato se non eseguito correttamente.

    
risposta data 19.10.2018 - 16:07
fonte

Leggi altre domande sui tag