sto cercando di popolare la cache in modo asincronoAsync chiamata entro funzione sincrona
static ConcurrentDictionary<string, string[]> data = new ConcurrentDictionary<string, string[]>();
public static async Task<string[]> GetStuffAsync(string key)
{
return data.GetOrAdd(key, async (x) => {
return await LoadAsync(x);
});
}
static async Task<string[]> LoadAsync(string key) {....}
ma questo mi dà l'errore:
Cannot convert async lambda expression to delegate type 'System.Func'.
An async lambda expression may return void, Task or Task, none of which are convertible to 'System.Func'.
quanto ho capito che questo è perché GetOrAdd()
non è asincrona. Come posso risolvere il problema?
Aggiornamento: LazyAsync
suggerito nei commenti lavorerà nel mio esempio banale. Oppure, soluzione come questo (può sicuramente vivere con un certo overhead introduce):
public static async Task<string[]> GetStuffAsync(string key)
{
string[] d = null;
if (!data.ContainsKey(key))
d = await LoadAsync(key);
return data.GetOrAdd(key, d);
}
La domanda allora diventa ha fatto Microsoft ha appena non hanno tempo per aggiornare tutte le interfacce per supportare asincrona o io sto cercando di fare qualcosa di profondamente sbagliato (e ConcurrentDictionary
non dovrebbe avere GetOrAddAsync()
)?
non è una risposta, ma forse è interessante per te: hai visto [AsyncLazy] (http://blogs.msdn.com/b/pfxteam/archive/2011/01/15/10116210.aspx)? – Default
Beh, non puoi farlo usando l'interfaccia che hai. 'await' funziona solo quando si trova su livelli asincroni e ne manchi uno: il metodo' GetOrAdd' stesso. Avresti bisogno di una versione che sia asincrona e attenda l'intero metodo 'GetOrAdd' (nota come non lo stai facendo in questo momento - questo è un altro problema). Purtroppo, questo significa scrivere il tuo ConcurrentDictionary, che farà male. – Luaan
Perché "ConcurrentDictionary" deve avere "GetOrAddAsync'? È una collezione sincrona in memoria. Non c'è motivo per avere un tale metodo. –