protected virtual async Task Update() { Logger.Write(this, LogLevel.Debug, "Updating {0} columns...", this.Columns.Count); var columns = new List <PlaylistColumn>(); using (var database = this.DatabaseFactory.Create()) { using (var task = new SingletonReentrantTask(CancellationToken.None, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = database.BeginTransaction(database.PreferredIsolationLevel)) { var set = database.Set <PlaylistColumn>(transaction); foreach (var pair in this.Columns) { Logger.Write(this, LogLevel.Debug, "Updating column {0} => {1}.", pair.Key.Id, pair.Key.Name); await set.AddOrUpdateAsync(pair.Key).ConfigureAwait(false); if (pair.Value) { columns.Add(pair.Key); } this.Columns.TryRemove(pair.Key); } transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } } if (columns.Any()) { await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistColumnsUpdated, columns.ToArray())).ConfigureAwait(false); } }
protected virtual async Task SynchronizePlaylistItems() { var playlistItems = default(IEnumerable <PlaylistItem>); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { var queryable = this.Database.AsQueryable <PlaylistItem>(transaction); //TODO: Add Enum.HasFlag support to FoxDb. playlistItems = queryable.Where(playlistItem => playlistItem.Flags == PlaylistItemFlags.Export).ToArray(); } #if NET40 return(TaskEx.FromResult(false)); #else return(Task.CompletedTask); #endif })) { await task.Run().ConfigureAwait(false); } if (!playlistItems.Any()) { return; } await this.MetaDataManager.Synchronize(playlistItems).ConfigureAwait(false); }
private async Task AddPlaylistItems() { this.Name = "Creating playlist"; this.Count = this.LibraryHierarchyNodes.Count(); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { var position = 0; foreach (var libraryHierarchyNode in this.LibraryHierarchyNodes) { if (this.IsCancellationRequested) { break; } this.Description = libraryHierarchyNode.Value; await this.AddPlaylistItems(this.Database.Queries.AddLibraryHierarchyNodeToPlaylist(this.Filter, this.Sort.Value), libraryHierarchyNode, transaction).ConfigureAwait(false); this.Position = ++position; } if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task MoveItems(IEnumerable <PlaylistItem> playlistItems) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { foreach (var playlistItem in playlistItems) { await this.Database.ExecuteAsync(this.Database.Queries.MovePlaylistItem, (parameters, phase) => { switch (phase) { case DatabaseParameterPhase.Fetch: parameters["id"] = playlistItem.Id; parameters["sequence"] = this.Sequence; break; } }, transaction).ConfigureAwait(false); if (playlistItem.Sequence > this.Sequence) { //TODO: If the current sequence is less than the target sequence we don't have to increment the counter. //TODO: I don't really understand why. this.Sequence++; } } transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task OnRun() { this.Name = "Opening CD"; try { if (!BassCd.IsReady(this.Drive)) { throw new InvalidOperationException("Drive is not ready."); } var playlist = this.PlaylistManager.SelectedPlaylist; var playlistItems = await this.Factory.Create().ConfigureAwait(false); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { //Always append for now. this.Sequence = this.PlaylistBrowser.GetInsertIndex(this.PlaylistManager.SelectedPlaylist); await this.AddPlaylistItems(playlist, playlistItems).ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } } finally { //Ignoring result on purpose. BassCd.Release(this.Drive); } await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistUpdated, new[] { this.Playlist })).ConfigureAwait(false); }
protected override async Task OnRun() { var position = 0; using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { var metaDataSource = this.MetaDataSourceFactory.Create(); foreach (var libraryItem in this.LibraryItems) { this.Description = Path.GetFileName(libraryItem.FileName); this.Position = position; if (!File.Exists(libraryItem.FileName)) { Logger.Write(this, LogLevel.Debug, "File \"{0}\" no longer exists: Cannot refresh.", libraryItem.FileName); continue; } var metaDatas = await metaDataSource.GetMetaData(libraryItem.FileName).ConfigureAwait(false); MetaDataItem.Update(metaDatas, libraryItem.MetaDatas, null); await this.WriteLibraryMetaData(libraryItem).ConfigureAwait(false); libraryItem.Status = LibraryItemStatus.Import; await LibraryTaskBase.UpdateLibraryItem(this.Database, libraryItem).ConfigureAwait(false); position++; } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task BuildHierarchies(LibraryItemStatus?status) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { await this.AddHiearchies(status, cancellationToken, transaction).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { this.Name = "Waiting.."; this.Description = string.Empty; } else { this.Name = "Finalizing"; this.Position = 0; this.Count = 0; } transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task OnRun() { var position = 0; using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { var metaDataSource = this.MetaDataSourceFactory.Create(); foreach (var libraryItem in this.LibraryItems) { await this.SetDescription(new FileInfo(libraryItem.FileName).Name).ConfigureAwait(false); await this.SetPosition(position).ConfigureAwait(false); if (!File.Exists(libraryItem.FileName)) { Logger.Write(this, LogLevel.Debug, "File \"{0}\" no longer exists: Cannot refresh.", libraryItem.FileName); continue; } libraryItem.MetaDatas = new ObservableCollection <MetaDataItem>( await metaDataSource.GetMetaData(libraryItem.FileName) .ConfigureAwait(false)); await this.WriteLibraryMetaData(libraryItem).ConfigureAwait(false); await LibraryTaskBase.SetLibraryItemStatus(this.Database, libraryItem.Id, LibraryItemStatus.Import).ConfigureAwait(false); position++; } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task RemoveItems(PlaylistItemStatus status) { await this.SetIsIndeterminate(true).ConfigureAwait(false); Logger.Write(this, LogLevel.Debug, "Removing playlist items."); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { await this.Database.ExecuteAsync(this.Database.Queries.RemovePlaylistItems, (parameters, phase) => { switch (phase) { case DatabaseParameterPhase.Fetch: parameters["status"] = status; break; } }, transaction).ConfigureAwait(false); transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task AddPlaylistItems(LibraryHierarchyNode libraryHierarchyNode, string filter) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { this.Offset = await this.Database.ExecuteScalarAsync <int>(this.Database.Queries.AddLibraryHierarchyNodeToPlaylist(filter, this.Sort.Value), (parameters, phase) => { switch (phase) { case DatabaseParameterPhase.Fetch: parameters["playlistId"] = this.Playlist.Id; parameters["libraryHierarchyId"] = libraryHierarchyNode.LibraryHierarchyId; parameters["libraryHierarchyItemId"] = libraryHierarchyNode.Id; parameters["sequence"] = this.Sequence; parameters["status"] = PlaylistItemStatus.Import; break; } }, transaction).ConfigureAwait(false); transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task AddPlaylistItems(IEnumerable <PlaylistItem> playlistItems) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { var set = this.Database.Set <PlaylistItem>(transaction); var position = 0; foreach (var playlistItem in PlaylistItem.Clone(playlistItems)) { Logger.Write(this, LogLevel.Debug, "Adding file to playlist: {0}", playlistItem.FileName); playlistItem.Playlist_Id = this.Playlist.Id; playlistItem.Sequence = this.Sequence + position; playlistItem.Status = PlaylistItemStatus.Import; await set.AddAsync(playlistItem).ConfigureAwait(false); position++; } this.Offset += position; if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task OnRun() { var position = 0; using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { var metaDataSource = this.MetaDataSourceFactory.Create(); foreach (var libraryItem in this.LibraryItems) { if (this.IsCancellationRequested) { break; } await this.SetDescription(new FileInfo(libraryItem.FileName).Name).ConfigureAwait(false); await this.SetPosition(position).ConfigureAwait(false); if (!File.Exists(libraryItem.FileName)) { Logger.Write(this, LogLevel.Debug, "File \"{0}\" no longer exists: Cannot update.", libraryItem.FileName); this.Errors.Add(libraryItem, new FileNotFoundException(string.Format("File \"{0}\" no longer exists: Cannot update.", libraryItem.FileName))); position++; continue; } try { await metaDataSource.SetMetaData( libraryItem.FileName, libraryItem.MetaDatas, metaDataItem => this.Names == null || !this.Names.Any() || this.Names.Contains(metaDataItem.Name, true) ).ConfigureAwait(false); } catch (Exception e) { this.Errors.Add(libraryItem, e); position++; continue; } foreach (var metaDataItem in libraryItem.MetaDatas.ToArray()) { if (!string.IsNullOrEmpty(metaDataItem.Value)) { continue; } libraryItem.MetaDatas.Remove(metaDataItem); } await this.WriteLibraryMetaData(libraryItem).ConfigureAwait(false); await LibraryTaskBase.SetLibraryItemStatus(this.Database, libraryItem.Id, LibraryItemStatus.Import).ConfigureAwait(false); position++; } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task RescanLibrary(IEnumerable <string> paths) { var predicate = new Func <LibraryItem, bool>(libraryItem => { if (!paths.Any(path => libraryItem.FileName.StartsWith(path))) { Logger.Write(this, LogLevel.Debug, "Removing unparented file: {0} => {1}", libraryItem.Id, libraryItem.FileName); return(true); } var file = new FileInfo(libraryItem.FileName); if (!file.Exists) { Logger.Write(this, LogLevel.Debug, "Removing dead file: {0} => {1}", libraryItem.Id, libraryItem.FileName); return(true); } if (file.LastWriteTimeUtc > libraryItem.GetImportDate()) { Logger.Write(this, LogLevel.Debug, "Refreshing modified file: {0} => {1}", libraryItem.Id, libraryItem.FileName); return(true); } return(false); }); var action = new Func <IDatabaseSet <LibraryItem>, LibraryItem, Task>(async(set, libraryItem) => { libraryItem.Status = LibraryItemStatus.Remove; //TODO: Writing to IDatabaseSet is not thread safe. Monitor.Enter(set); try { await set.AddOrUpdateAsync(libraryItem).ConfigureAwait(false); } finally { Monitor.Exit(set); } }); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { using (var libraryUpdater = new LibraryUpdater(this.Database, Enumerable.Empty <LibraryItem>(), predicate, action, this.Visible, transaction)) { libraryUpdater.InitializeComponent(this.Core); await this.WithSubTask(libraryUpdater, () => libraryUpdater.Populate(cancellationToken) ).ConfigureAwait(false); } if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
public async Task SingletonReentrantTaskRespectsPriority() { var counter1 = 0; var counter2 = 0; var id = "5C8A060E-885C-4FF1-ABEB-DB046D2D8D1C"; var task1 = new SingletonReentrantTask(Placeholder.Instance, id, 10, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { for (; counter1 + counter2 < 10; counter1++) { if (cancellationToken.IsCancellationRequested) { break; } #if NET40 await TaskEx.Delay(100).ConfigureAwait(false); #else await Task.Delay(100).ConfigureAwait(false); #endif } }); var task2 = new SingletonReentrantTask(Placeholder.Instance, id, 10, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { for (; counter1 + counter2 < 10; counter2++) { if (cancellationToken.IsCancellationRequested) { break; } #if NET40 await TaskEx.Delay(100).ConfigureAwait(false); #else await Task.Delay(100).ConfigureAwait(false); #endif } }); #if NET40 await TaskEx.WhenAll(task1.Run(), task2.Run()).ConfigureAwait(false); #else await Task.WhenAll(task1.Run(), task2.Run()).ConfigureAwait(false); #endif Assert.AreEqual(10, counter1 + counter2); Assert.Less(counter1, counter2); }
protected override async Task AddPaths(IEnumerable <string> paths) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { await this.AddPlaylistItems(paths, cancellationToken).ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.SequenceItems().ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task AddPaths(IEnumerable <string> paths, bool buildHierarchies) { var complete = true; using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { await this.AddLibraryItems(paths, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { await this.SetName("Waiting..").ConfigureAwait(false); await this.SetDescription(string.Empty).ConfigureAwait(false); } })) { await task.Run().ConfigureAwait(false); } if (this.IsCancellationRequested) { //Reset cancellation as the next phases should finish quickly. //Cancelling again will still work. this.IsCancellationRequested = false; complete = false; } using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_LOW, async cancellationToken => { await this.AddOrUpdateMetaData(cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { await this.SetName("Waiting..").ConfigureAwait(false); await this.SetDescription(string.Empty).ConfigureAwait(false); } })) { await task.Run().ConfigureAwait(false); } if (this.IsCancellationRequested) { //Reset cancellation as the next phases should finish quickly. //Cancelling again will still work. this.IsCancellationRequested = false; complete = false; } if (buildHierarchies) { await this.BuildHierarchies(LibraryItemStatus.Import).ConfigureAwait(false); } if (complete) { await SetLibraryItemsStatus(this.Database, LibraryItemStatus.None).ConfigureAwait(false); } }
protected virtual async Task AddPaths(IEnumerable <string> paths) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { await this.AddPlaylistItems(paths, cancellationToken).ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistUpdated, new[] { this.Playlist })).ConfigureAwait(false); await this.AddOrUpdateMetaData(cancellationToken).ConfigureAwait(false); await this.SequenceItems().ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task RemoveItems(PlaylistItemStatus status) { Logger.Write(this, LogLevel.Debug, "Removing playlist items."); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { await RemovePlaylistItems(this.Database, this.Playlist.Id, status, transaction).ConfigureAwait(false); transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task OnRun() { var position = 0; using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { foreach (var playlistItem in this.PlaylistItems) { if (this.IsCancellationRequested) { break; } if (this.Visible) { this.Description = Path.GetFileName(playlistItem.FileName); this.Position = position; } if (playlistItem.LibraryItem_Id.HasValue) { await this.WriteLibraryMetaData(playlistItem).ConfigureAwait(false); await LibraryTaskBase.UpdateLibraryItem( this.Database, playlistItem.LibraryItem_Id.Value, libraryItem => libraryItem.Status = LibraryItemStatus.Import ).ConfigureAwait(false); } else { await this.WritePlaylistMetaData(playlistItem).ConfigureAwait(false); } if (this.WriteToFiles) { if (!await this.MetaDataManager.Synchronize(new[] { playlistItem }, this.Names.ToArray()).ConfigureAwait(false)) { this.AddError(playlistItem, string.Format("Failed to write meta data to file \"{0}\". We will try again later.", playlistItem.FileName)); } } position++; } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task AddPaths(IEnumerable <string> paths) { var libraryItems = await this.Factory.Create(paths).ConfigureAwait(false); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { await this.RemoveLibraryItems().ConfigureAwait(false); await this.AddLibraryItems(libraryItems).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } await this.BuildHierarchies(LibraryItemStatus.Import).ConfigureAwait(false); await RemoveCancelledLibraryItems(this.Database).ConfigureAwait(false); await SetLibraryItemsStatus(this.Database, LibraryItemStatus.None).ConfigureAwait(false); }
protected override async Task OnRun() { var cueSheet = this.Parser.Parse(this.FileName); var playlistItems = await this.Factory.Create(cueSheet).ConfigureAwait(false); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { await this.AddPlaylistItems(playlistItems).ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistUpdated, new[] { this.Playlist })).ConfigureAwait(false); }
private async Task AddPlaylistItems() { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { await this.AddPlaylistItems(this.Database.Queries.AddSearchToPlaylist(this.Filter, this.Sort, this.Limit), transaction).ConfigureAwait(false); if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task RemovePlaylist() { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { var set = this.Database.Set <Playlist>(transaction); await set.RemoveAsync(this.Playlist).ConfigureAwait(false); if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
protected virtual async Task Update(Playlist playlist) { using (var database = this.DatabaseFactory.Create()) { using (var task = new SingletonReentrantTask(CancellationToken.None, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = database.BeginTransaction(database.PreferredIsolationLevel)) { var set = database.Set <Playlist>(transaction); await set.AddOrUpdateAsync(playlist).ConfigureAwait(false); transaction.Commit(); } })) { await task.Run().ConfigureAwait(false); } } }
protected override async Task OnRun() { this.Name = "Opening archive"; var playlistItems = await this.Factory.Create().ConfigureAwait(false); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { //Always append for now. this.Sequence = this.PlaylistBrowser.GetInsertIndex(this.Playlist); await this.AddPlaylistItems(this.Playlist, playlistItems).ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistUpdated, new[] { this.Playlist })).ConfigureAwait(false); }
protected virtual async Task RemoveItems(IEnumerable <PlaylistItem> playlistItems) { using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { foreach (var playlistItem in playlistItems) { playlistItem.Status = PlaylistItemStatus.Remove; } var set = this.Database.Set <PlaylistItem>(transaction); await set.AddOrUpdateAsync(playlistItems).ConfigureAwait(false); if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } await this.RemoveItems(PlaylistItemStatus.Remove).ConfigureAwait(false); }
protected virtual async Task SortItems(IComparer <PlaylistItem> comparer, bool descending) { Logger.Write(this, LogLevel.Debug, "Sorting playlist using comparer: \"{0}\"", comparer.GetType().Name); using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { using (var transaction = this.Database.BeginTransaction(this.Database.PreferredIsolationLevel)) { var set = this.Database.Set <PlaylistItem>(transaction); var playlistItems = set.ToArray(); Array.Sort(playlistItems, comparer); if (descending) { Logger.Write(this, LogLevel.Debug, "Sort is descending, reversing sequence."); Array.Reverse(playlistItems); } for (var a = 0; a < playlistItems.Length; a++) { playlistItems[a].Sequence = a; } await EntityHelper <PlaylistItem> .Create( this.Database, this.Database.Tables.PlaylistItem, transaction ).UpdateAsync( playlistItems, new[] { nameof(PlaylistItem.Sequence) } ).ConfigureAwait(false); if (transaction.HasTransaction) { transaction.Commit(); } } })) { await task.Run().ConfigureAwait(false); } }
protected override async Task OnRun() { if (this.Drive == BassCdStreamProviderBehaviourConfiguration.CD_NO_DRIVE) { throw new InvalidOperationException("A valid drive must be provided."); } await this.SetName("Opening CD").ConfigureAwait(false); await this.SetIsIndeterminate(true).ConfigureAwait(false); try { if (!BassCd.IsReady(this.Drive)) { throw new InvalidOperationException("Drive is not ready."); } using (var task = new SingletonReentrantTask(this, ComponentSlots.Database, SingletonReentrantTask.PRIORITY_HIGH, async cancellationToken => { //Always append for now. this.Sequence = await this.PlaylistBrowser.GetInsertIndex().ConfigureAwait(false); await this.AddPlaylistItems().ConfigureAwait(false); await this.ShiftItems(QueryOperator.GreaterOrEqual, this.Sequence, this.Offset).ConfigureAwait(false); await this.AddOrUpdateMetaData().ConfigureAwait(false); await this.SetPlaylistItemsStatus(PlaylistItemStatus.None).ConfigureAwait(false); })) { await task.Run().ConfigureAwait(false); } } finally { //Ignoring result on purpose. BassCd.Release(this.Drive); } await this.SignalEmitter.Send(new Signal(this, CommonSignals.PlaylistUpdated)).ConfigureAwait(false); }