ease up on artist task concurrency

This commit is contained in:
Luke Pulverenti 2013-09-25 18:36:48 -04:00
parent fca5a40601
commit 262dc6d8cd

View file

@ -185,7 +185,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param> /// <param name="progress">The progress.</param>
/// <returns>Task{Artist[]}.</returns> /// <returns>Task{Artist[]}.</returns>
private async Task<ConcurrentBag<Artist>> GetAllArtists(IEnumerable<Audio> allSongs, CancellationToken cancellationToken, IProgress<double> progress) private async Task<List<Artist>> GetAllArtists(IEnumerable<Audio> allSongs, CancellationToken cancellationToken, IProgress<double> progress)
{ {
var allArtists = allSongs var allArtists = allSongs
.SelectMany(i => .SelectMany(i =>
@ -203,60 +203,36 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToList(); .ToList();
const int maxTasks = 3; var returnArtists = new List<Artist>(allArtists.Count);
var tasks = new List<Task>();
var returnArtists = new ConcurrentBag<Artist>();
var numComplete = 0; var numComplete = 0;
var numArtists = allArtists.Count; var numArtists = allArtists.Count;
foreach (var artist in allArtists) foreach (var artist in allArtists)
{ {
if (tasks.Count > maxTasks) cancellationToken.ThrowIfCancellationRequested();
{
await Task.WhenAll(tasks).ConfigureAwait(false);
tasks.Clear();
// Safe cancellation point, when there are no pending tasks try
cancellationToken.ThrowIfCancellationRequested(); {
var artistItem = _libraryManager.GetArtist(artist);
await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
returnArtists.Add(artistItem);
}
catch (IOException ex)
{
_logger.ErrorException("Error validating Artist {0}", ex, artist);
} }
// Avoid accessing the foreach variable within the closure // Update progress
var currentArtist = artist; numComplete++;
double percent = numComplete;
percent /= numArtists;
tasks.Add(Task.Run(async () => progress.Report(100 * percent);
{
cancellationToken.ThrowIfCancellationRequested();
try
{
var artistItem = _libraryManager.GetArtist(currentArtist);
await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
returnArtists.Add(artistItem);
}
catch (IOException ex)
{
_logger.ErrorException("Error validating Artist {0}", ex, currentArtist);
}
// Update progress
lock (progress)
{
numComplete++;
double percent = numComplete;
percent /= numArtists;
progress.Report(100 * percent);
}
}));
} }
await Task.WhenAll(tasks).ConfigureAwait(false);
return returnArtists; return returnArtists;
} }