Tutto, ecco una domanda sulla progettazione/le migliori pratiche di un caso complesso di annullamento Attività: s in C#. Come implementate la cancellazione di un'attività condivisa?Come implementare l'annullamento dell'attività condivisa: s in C#
Come esempio minimo, si assume quanto segue; abbiamo un'operazione "Lavoro" che si può annullare in modo cooperativo e di lunga durata. Accetta un token di cancellazione come argomento e lancia se è stato cancellato. Funziona su alcuni stati dell'applicazione e restituisce un valore. Il suo risultato è richiesto in modo indipendente da due componenti dell'interfaccia utente.
Mentre lo stato dell'applicazione è invariato, il valore della funzione di lavoro deve essere memorizzato nella cache e se un calcolo è in corso, una nuova richiesta non deve iniziare un secondo calcolo, ma piuttosto iniziare ad attendere un risultato.
Uno dei componenti dell'interfaccia utente dovrebbe essere in grado di annullare l'attività senza influire sull'attività dei componenti dell'interfaccia utente.
Sei con me fino ad ora?
Quanto sopra può essere realizzato introducendo una cache delle attività che avvolge la reale attività di lavoro in TaskCompletionSources, le cui attività vengono quindi restituite ai componenti dell'interfaccia utente. Se un componente dell'interfaccia utente annulla la sua attività, abbandona solo TaskCompletionSource Task e non l'attività sottostante. Va tutto bene. I componenti dell'interfaccia utente creano l'origine di annullamento e la richiesta di annullamento è un normale disegno dall'alto verso il basso, con l'attività TaskCompletionSource che collabora in basso.
Ora, per il vero problema. Cosa fare quando lo stato dell'applicazione cambia? Supponiamo che la funzione "Lavoro" funzioni su una copia dello stato non sia fattibile.
Una soluzione sarebbe quella di ascoltare il cambiamento di stato nella cache delle attività (o circa). Se la cache ha un metodo di annullamento utilizzato dall'attività sottostante, quella che esegue la funzione Lavoro, potrebbe annullarla. Ciò potrebbe quindi innescare l'annullamento di tutte le attività TaskCompletionSources allegate: s, e quindi entrambe le componenti dell'interfaccia utente otterrebbero attività annullate. Questa è una sorta di cancellazione dal basso.
C'è un modo preferito per farlo? Esiste uno schema di progettazione che lo descrive in qualche dove?
L'annullamento dal basso verso l'alto può essere implementato, ma si sente un po 'strano. L'UI-task viene creato con un CancellationToken, ma viene cancellato a causa di un altro (Internal) CancellationToken. Inoltre, poiché i token non sono uguali, OperationCancelledException non può essere semplicemente ignorato nell'interfaccia utente - ciò potrebbe (eventualmente) portare a un'eccezione generata nel finalizzatore Task esterno.
Ottima domanda, anche se la mia prima reazione è stata "tl; dr" – dtb
Quindi, per chiarire; si hanno due utenti del risultato dell'attività e si desidera che una sola attività calcoli il valore per stato dell'applicazione; eppure vuoi che ogni consumatore sia in grado di "annullare" in attesa del risultato dell'attività? – Tejs
sì, ma anche che un cambiamento di stato dovrebbe annullare il calcolo. – 4ZM