public async Task <T> GetAsync(string key) { Clean(); ItemLock <T> progressLock = null; ItemLock <T> ownProgressLock = null; T res = null; lock (instanceLock) { if (items.ContainsKey(key)) { progressLock = items[key]; } else { ownProgressLock = new ItemLock <T>(); items[key] = ownProgressLock; } } if (ownProgressLock != null) { try { res = await cacheMissedHandlerAsync(key); } catch { res = null; } // dont keep in cache loading failures if (!allowNullCaching && res == null) { lock (instanceLock) { items.Remove(key); } } lock (ownProgressLock) { ownProgressLock.Data = res; ownProgressLock.Done = true; Monitor.PulseAll(ownProgressLock); } } if (progressLock != null) { lock (progressLock) { if (!progressLock.Done) { Monitor.Wait(progressLock); } } res = progressLock.Data; } return(res); }
public string GetItem(string key) { //Random rand = new Random(); //bool clean = (rand.Next(100) == 1); //if(clean) Clean(); ItemLock itemLock = null; lock (lockInstance) { if (inprogress.ContainsKey(key)) { itemLock = inprogress[key]; } else { itemLock = new ItemLock(); inprogress[key] = itemLock; } } long id = -1; try { lock (itemLock) { if (!itemLock.Done) { string connectionString = "URI=file:" + basePath + "cache.db"; using (IDbConnection dbcon = (IDbConnection) new SqliteConnection(connectionString)) { dbcon.Open(); // get the item using (IDbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = "SELECT id FROM item WHERE key='" + key.Replace("'", "''") + "' AND last > DATETIME('now', '-" + timeout + " seconds')"; object res = dbcmd.ExecuteScalar(); if (res != null) { id = Convert.ToInt64(res); } } // if not found, get a new version if (id == -1) { string validity; string file = handler(key, out validity); if (file != null) { using (IDbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = "INSERT INTO item (key,validity,last) VALUES ('" + key.Replace("'", "''") + "','" + validity.Replace("'", "''") + "',DATETIME('now'))"; dbcmd.ExecuteNonQuery(); } // get the insert id using (IDbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = "SELECT last_insert_rowid()"; id = Convert.ToInt64(dbcmd.ExecuteScalar()); } File.Move(file, basePath + "/data/" + id.ToString()); } } dbcon.Close(); } if (id != -1) { itemLock.File = basePath + "/data/" + id.ToString(); } else { itemLock.File = null; } } } } catch (Exception) { } finally { lock (lockInstance) { if (inprogress.ContainsKey(key)) { inprogress.Remove(key); } } } return(itemLock.File); }