public async Task <bool> DownloadRepo(string user, string repo, string commitId) { var cacheDir = Path.Combine(AppConfiguration["cacheDir"], user, repo, commitId); //已經有快取項目 if (Directory.Exists(cacheDir)) { return(true); } // 檢查目前是否正在下載中了 lock (DownloadLocker) { // 沒在下載中 if (!DownloadLocker.ContainsKey(commitId)) { // 建立lock物件 DownloadLocker[commitId] = new object(); } } // 標註正在被locking的數量 lock (Locking) { if (!Locking.ContainsKey(commitId)) { Locking[commitId] = 0; } Locking[commitId]++; } lock (DownloadLocker[commitId]) { // 如果快取項目,其他request在lock期間已經完成下載 if (!Directory.Exists(cacheDir)) { var url = $"{AppConfiguration["giteaHost"]}/{user}/{repo}/archive/{commitId}.zip"; HttpClient client = new HttpClient(); Stream downloadStream = null; try { downloadStream = client.GetStreamAsync(url).GetAwaiter().GetResult(); } catch { // 無法取得串流 return(false); } using (ZipArchive arch = new ZipArchive(downloadStream, ZipArchiveMode.Read, true)) { arch.ExtractToDirectory(cacheDir, true); } } } // 解鎖 Locking[commitId]--; return(true); }
public PagesController(LiteDatabase database) { this.Database = database; if (LockClear == null) { LockClear = Task.Run(() => { for (; ;) { Thread.Sleep(TimeSpan.FromSeconds(30)); lock (Locking) { var willDelete = Locking.Where(x => x.Value == 0).ToArray(); foreach (var commit in willDelete) { DownloadLocker.Remove(commit.Key); Locking.Remove(commit.Key); } } } }); } }