public Task GetModelDataAsync(string name, ModelDataDelegate callback) { name = Path.GetFileNameWithoutExtension(name); Task t = null; if (_modelData.ContainsKey(name)) { callback(new ModelData() { Data = _modelData[name], Name = name }); } else { t = Task.Factory.StartNew(() => Download(name, callback, t)); } return(t); }
private void Download(string name, ModelDataDelegate callback, Task task) { Task conflictingTask = null; lock (_tasks) { if (!_tasks.ContainsKey(name)) { _tasks.Add(name, task); } else { if (_tasks.ContainsKey(name) && _tasks[name].Id != task.Id) { conflictingTask = _tasks[name]; } } } if (conflictingTask != null) { Debug.WriteLine("Waiting for other task to finish."); if (!conflictingTask.IsCompleted) { conflictingTask.Wait(); } } var model = Path.Combine(_modelPath, Path.GetFileNameWithoutExtension(name) + ".zip"); if (File.Exists(model)) { Debug.WriteLine("Reading and unzipping model from file system."); var zip = ZipStorer.Open(model, FileAccess.Read); var dir = zip.ReadCentralDir(); if (dir.Count == 0) { lock (_tasks) { _tasks.Remove(name); } callback(new ModelData { Data = string.Empty, Exception = new Exception("No such model found."), Name = name }); } using (var mem = new MemoryStream()) { zip.ExtractFile(dir[0], mem); zip.Close(); mem.Position = 0; using (var sr = new StreamReader(mem)) { var data = sr.ReadToEnd(); lock (_tasks) { _tasks.Remove(name); } if (!_modelData.ContainsKey(name)) { _modelData.Add(name, data); } callback(new ModelData { Data = data, Name = name }); } } //task.Dispose(); return; } Debug.WriteLine("Downloading model from internet."); using (var webClient = new WebClient()) { try { webClient.DownloadFile( Path.Combine(_remoteModelPath, Path.GetFileNameWithoutExtension(name) + ".zip"), model); // recurse to read the file which was saved to harddisk. lock (_tasks) { _tasks.Remove(name); } Download(name, callback, task); } catch (Exception ex) { lock (_tasks) { _tasks.Remove(name); } callback(new ModelData { Name = name, Data = string.Empty, Exception = ex }); } } //task.Dispose(); }