private void UpdateTagsThread() { Song song; bool fixErrors = DateTime.Now > _lastFixErrors + TimeSpan.FromMinutes(2); List <ManualResetEvent> doneEvents = new List <ManualResetEvent>(); Config.ConfigFile config = SongPlayerFactory.GetConfigFile(); string[] extensionsArray = config.GetValue("library.extensions").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.StartsWith(".", StringComparison.OrdinalIgnoreCase) ? x : "." + x) .ToArray(); HashSet <string> extensions = new HashSet <string>(extensionsArray, StringComparer.OrdinalIgnoreCase); if (extensions.Count == 0) { extensions.Add(".mp3"); } do { //Lock collection as short as possible lock (lockObject) { if (fixErrors) { song = _songs.Values.FirstOrDefault(s => s.TagRead == false); } else { song = _songs.Values.FirstOrDefault(s => s.TagRead == false && s.ErrorReadingTag == false); } } if (song != null) { if (extensions.Contains(song.Extension)) { if (song.ErrorReadingTag) { _lastFixErrors = DateTime.Now; } // update song UpdateSingleTag(song); _updatedTag = true; } } // loop until no song found } while (song != null); // finished this run _updateRunning = false; }
private void ScanSongsThread() { Config.ConfigFile config = SongPlayerFactory.GetConfigFile(); string[] directories = config.GetValue("library.path").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); string[] extensionsArray = config.GetValue("library.extensions").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.StartsWith(".", StringComparison.OrdinalIgnoreCase) ? x : "." + x) .ToArray(); HashSet <string> extensions = new HashSet <string>(extensionsArray, StringComparer.OrdinalIgnoreCase); if (extensions.Count == 0) { extensions.Add(".mp3"); } HashSet <string> files = new HashSet <string>(StringComparer.OrdinalIgnoreCase); //assuming we could have several dirs here, lets speed up the process Parallel.ForEach(directories, directory => { if (Directory.Exists(directory)) { HashSet <string> filesFound = GetFilesRecursive(directory, extensions); // lock files object lock (lockObject) { files.UnionWith(filesFound); } } }); //Find removed songs lock (lockObject) { string[] keysToRemove = _songs.Keys.Where(x => !files.Contains(x, StringComparer.OrdinalIgnoreCase)).ToArray(); foreach (string key in keysToRemove) { if (_songs.Remove(key)) { _scanFoundChange = true; } } } //Find added songs. Here we can have thousands of files Parallel.ForEach(files, fileName => { bool checkNext = false; lock (lockObject) { if (_songs.ContainsKey(fileName)) { checkNext = true; } } if (!checkNext) { FileInfo fileInfo = new FileInfo(fileName); Song song = new Song(); song.FileName = fileName; song.Extension = fileInfo.Extension; song.Name = Regex.Replace(fileInfo.Name, @"\" + fileInfo.Extension + "$", string.Empty, RegexOptions.IgnoreCase); song.DateCreated = fileInfo.CreationTime.ToString("yyyy-MM-dd HH:mm"); song.GenerateSearchAndDoubleMetaphone(); lock (lockObject) { _songs.Add(fileName, song); } _scanFoundChange = true; } }); _scanRunning = false; }
private void Deserialize() { try { lock (lockObject) { if (File.Exists("library.bin")) { Config.ConfigFile config = SongPlayerFactory.GetConfigFile(); string[] extensionsArray = config.GetValue("library.extensions").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.StartsWith(".", StringComparison.OrdinalIgnoreCase) ? x : "." + x) .ToArray(); HashSet <string> extensions = new HashSet <string>(extensionsArray, StringComparer.OrdinalIgnoreCase); if (extensions.Count == 0) { extensions.Add(".mp3"); } using (Stream stream = File.Open("library.bin", FileMode.Open)) { if (stream.Length > 0) { BinaryFormatter bin = new BinaryFormatter(); object fromLibrary = bin.Deserialize(stream); if (fromLibrary is List <Song> ) { List <Song> songs = (List <Song>)fromLibrary; foreach (Song song in songs) { // only add supported songs if (extensions.Contains(song.Extension)) { song.GenerateSearchAndDoubleMetaphone(); _songs.Add(song.FileName, song); } } } else if (fromLibrary is Dictionary <string, Song> ) { Dictionary <string, Song> songs = (Dictionary <string, Song>)fromLibrary; foreach (Song song in songs.Values) { // only add supported songs if (extensions.Contains(song.Extension)) { song.GenerateSearchAndDoubleMetaphone(); _songs.Add(song.FileName, song); } } } else if (fromLibrary is Dictionary <string, Song> .ValueCollection) { Dictionary <string, Song> .ValueCollection valueCollection = (Dictionary <string, Song> .ValueCollection)fromLibrary; List <Song> songs = valueCollection.ToList(); foreach (Song song in songs) { // only add supported songs if (extensions.Contains(song.Extension)) { song.GenerateSearchAndDoubleMetaphone(); _songs.Add(song.FileName, song); } } } else { throw new Exception(string.Format("Songs saved in unknown type '{0}'!", fromLibrary.GetType().Name)); } // can't be dirty when just deserialized... List <Song> dirtySongs = _songs.Values.Where(x => x.IsDirty).ToList(); foreach (Song song in dirtySongs) { song.IsDirty = false; } } } } } OnStatusChanged("Loaded library containing " + _songs.Count() + " songs"); } catch (Exception) { OnStatusChanged("Error loading library..."); } _unsavedChanges = false; }