L'applicazione che sto sviluppando richiede che alcuni dati siano ottenuti attraverso diversi canali. Poiché si tratta di un processo di rete, ho deciso di utilizzare la programmazione asincrona.
Ho progettato la seguente interfaccia per rappresentare tutti i canali possibili:
public interface IMyDataChannel
{
Task<MyData> GetMyDataAsync(/* parameters not relevant to the question */);
}
Ho bisogno di ottenere questi dati con parametri diversi, e da canali diversi a volte, quindi idealmente dovrei lanciare tutte le richieste in parallelo per la migliore performance.
Il problema è che uno dei canali è molto instabile, e se lancio diverse richieste in parallelo, o anche sequenzialmente, sovraccarica e restituisce risultati imprevisti. Devo assicurarmi che questo canale non supporti le richieste parallele e aspetta un po 'di tempo dopo ogni richiesta, per evitare di sovraccaricarlo.
Penso che questa logica appartenga all'implementazione del canale, perché i chiamanti non dovrebbero sapere se il canale sottostante è stabile o meno. Invece, dovrebbero recuperare i dati dai canali in modo unificato.
In primo luogo, pensavo che avrei potuto usare un blocco statico nell'implementazione del canale instabile e assicurarmi che il processo desse per qualche tempo prima di rilasciare il blocco. L'implementazione sarebbe come questa:
public class UnstableMyDataChannel : IMyDataChannel
{
private const int stabilityDelay = 1000;
private static readonly object stabilityLock = new object();
public async Task<MyData> GetMyDataAsync(/* parameters not relevant to the question */)
{
lock(stabilityLock)
{
//Throws a compiler error because you can't "await" inside a "lock"
MyData data = await PrivateMethodsForRetrievingDataAsync(/* parameters not relevant to the question */);
//Throws a compiler error because you can't "await" inside a "lock"
await Task.Delay(stabilityDelay);
return data;
}
}
}
Tuttavia, non è possibile attendere nulla all'interno di un'istruzione di blocco. Anche se tu potessi, questo design non mi convince completamente. Qualcuno può fornire una soluzione migliore (e possibile)?