diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 6543275a54..497226dbb1 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -304,14 +304,6 @@ namespace MediaBrowser.Controller.Entities
///
private ItemResolveArgs _resolveArgs;
///
- /// The _resolve args initialized
- ///
- private bool _resolveArgsInitialized;
- ///
- /// The _resolve args sync lock
- ///
- private object _resolveArgsSyncLock = new object();
- ///
/// We attach these to the item so that we only ever have to hit the file system once
/// (this includes the children of the containing folder)
///
@@ -321,26 +313,24 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- try
+ if (_resolveArgs == null)
{
- LazyInitializer.EnsureInitialized(ref _resolveArgs, ref _resolveArgsInitialized, ref _resolveArgsSyncLock, () => CreateResolveArgs());
- }
- catch (IOException ex)
- {
- Logger.ErrorException("Error creating resolve args for {0}", ex, Path);
+ try
+ {
+ _resolveArgs = CreateResolveArgs();
+ }
+ catch (IOException ex)
+ {
+ Logger.ErrorException("Error creating resolve args for {0}", ex, Path);
- IsOffline = true;
+ IsOffline = true;
- throw;
+ throw;
+ }
}
return _resolveArgs;
}
- private set
- {
- _resolveArgs = value;
- _resolveArgsInitialized = value != null;
- }
}
///
@@ -354,12 +344,12 @@ namespace MediaBrowser.Controller.Entities
public void ResetResolveArgs()
{
- ResolveArgs = null;
+ _resolveArgs = null;
}
public void ResetResolveArgs(ItemResolveArgs args)
{
- ResolveArgs = args;
+ _resolveArgs = args;
}
///
@@ -759,7 +749,7 @@ namespace MediaBrowser.Controller.Entities
if (dbItem != null)
{
- dbItem.ResolveArgs = video.ResolveArgs;
+ dbItem.ResetResolveArgs(video.ResolveArgs);
video = dbItem;
}
@@ -820,7 +810,7 @@ namespace MediaBrowser.Controller.Entities
if (dbItem != null)
{
- dbItem.ResolveArgs = audio.ResolveArgs;
+ dbItem.ResetResolveArgs(audio.ResolveArgs);
audio = dbItem;
}
@@ -878,7 +868,7 @@ namespace MediaBrowser.Controller.Entities
if (dbItem != null)
{
- dbItem.ResolveArgs = item.ResolveArgs;
+ dbItem.ResetResolveArgs(item.ResolveArgs);
item = dbItem;
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 2ba16ab038..084f9b05c3 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -708,65 +708,6 @@ namespace MediaBrowser.Server.Implementations.Library
return obj as T;
}
- ///
- /// Generically retrieves an IBN item
- ///
- ///
- /// The path.
- /// The name.
- /// The cancellation token.
- /// if set to true [allow slow providers].
- /// if set to true [force creation].
- /// Task{``0}.
- ///
- ///
- private async Task GetItemByName(string path, string name, CancellationToken cancellationToken, bool allowSlowProviders = true, bool refreshMetadata = false)
- where T : BaseItem, new()
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException();
- }
-
- if (string.IsNullOrEmpty(name))
- {
- throw new ArgumentNullException();
- }
-
- var validFilename = FileSystem.GetValidFilename(name);
-
- var key = Path.Combine(path, validFilename);
-
- BaseItem obj;
-
- if (!_itemsByName.TryGetValue(key, out obj))
- {
- var tuple = CreateItemByName(key, name);
-
- obj = tuple.Item2;
-
- _itemsByName.AddOrUpdate(key, obj, (keyName, oldValue) => obj);
-
- try
- {
- await obj.RefreshMetadata(cancellationToken, tuple.Item1, allowSlowProviders: allowSlowProviders).ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
- BaseItem removed;
- _itemsByName.TryRemove(key, out removed);
-
- throw;
- }
- }
- else if (refreshMetadata)
- {
- await obj.RefreshMetadata(cancellationToken, false, allowSlowProviders: allowSlowProviders).ConfigureAwait(false);
- }
-
- return obj as T;
- }
-
///
/// Creates an IBN item based on a given path
///
@@ -846,7 +787,7 @@ namespace MediaBrowser.Server.Implementations.Library
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
- catch (IOException ex)
+ catch (Exception ex)
{
_logger.ErrorException("Error validating IBN entry {0}", ex, person.Name);
}
@@ -963,12 +904,16 @@ namespace MediaBrowser.Server.Implementations.Library
progress.Report(2);
+ var innerProgress = new ActionableProgress();
+
+ innerProgress.RegisterAction(pct => progress.Report(2 + pct * .13));
+
// Run prescan tasks
- await RunPrescanTasks(progress, cancellationToken).ConfigureAwait(false);
+ await RunPrescanTasks(innerProgress, cancellationToken).ConfigureAwait(false);
progress.Report(15);
- var innerProgress = new ActionableProgress();
+ innerProgress = new ActionableProgress();
innerProgress.RegisterAction(pct => progress.Report(15 + pct * .6));
@@ -977,8 +922,12 @@ namespace MediaBrowser.Server.Implementations.Library
progress.Report(75);
+ innerProgress = new ActionableProgress();
+
+ innerProgress.RegisterAction(pct => progress.Report(75 + pct * .25));
+
// Run post-scan tasks
- await RunPostScanTasks(progress, cancellationToken).ConfigureAwait(false);
+ await RunPostScanTasks(innerProgress, cancellationToken).ConfigureAwait(false);
progress.Report(100);
@@ -995,41 +944,45 @@ namespace MediaBrowser.Server.Implementations.Library
/// Task.
private async Task RunPrescanTasks(IProgress progress, CancellationToken cancellationToken)
{
- var prescanTasks = PrescanTasks.ToList();
- var progressDictionary = new Dictionary();
+ var tasks = PrescanTasks.ToList();
- var tasks = prescanTasks.Select(i => Task.Run(async () =>
+ var numComplete = 0;
+ var numTasks = tasks.Count;
+
+ foreach (var task in tasks)
{
var innerProgress = new ActionableProgress();
+ // Prevent access to modified closure
+ var currentNumComplete = numComplete;
+
innerProgress.RegisterAction(pct =>
{
- lock (progressDictionary)
- {
- progressDictionary[i] = pct;
-
- double percent = progressDictionary.Values.Sum();
- percent /= prescanTasks.Count;
-
- progress.Report(2 + percent * .13);
- }
+ double innerPercent = (currentNumComplete * 100) + pct;
+ innerPercent /= numTasks;
+ progress.Report(innerPercent);
});
try
{
- await i.Run(innerProgress, cancellationToken);
+ await task.Run(innerProgress, cancellationToken);
}
catch (OperationCanceledException)
{
- _logger.Info("Pre-scan task cancelled: {0}", i.GetType().Name);
+ _logger.Info("Pre-scan task cancelled: {0}", task.GetType().Name);
}
catch (Exception ex)
{
- _logger.ErrorException("Error running prescan task", ex);
+ _logger.ErrorException("Error running pre-scan task", ex);
}
- }));
- await Task.WhenAll(tasks).ConfigureAwait(false);
+ numComplete++;
+ double percent = numComplete;
+ percent /= numTasks;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
}
///
@@ -1040,41 +993,45 @@ namespace MediaBrowser.Server.Implementations.Library
/// Task.
private async Task RunPostScanTasks(IProgress progress, CancellationToken cancellationToken)
{
- var postscanTasks = PostscanTasks.ToList();
- var progressDictionary = new Dictionary();
+ var tasks = PostscanTasks.ToList();
- var tasks = postscanTasks.Select(i => Task.Run(async () =>
+ var numComplete = 0;
+ var numTasks = tasks.Count;
+
+ foreach (var task in tasks)
{
var innerProgress = new ActionableProgress();
+ // Prevent access to modified closure
+ var currentNumComplete = numComplete;
+
innerProgress.RegisterAction(pct =>
{
- lock (progressDictionary)
- {
- progressDictionary[i] = pct;
-
- double percent = progressDictionary.Values.Sum();
- percent /= postscanTasks.Count;
-
- progress.Report(75 + percent * .25);
- }
+ double innerPercent = (currentNumComplete * 100) + pct;
+ innerPercent /= numTasks;
+ progress.Report(innerPercent);
});
try
{
- await i.Run(innerProgress, cancellationToken);
+ await task.Run(innerProgress, cancellationToken);
}
catch (OperationCanceledException)
{
- _logger.Info("Post-scan task cancelled: {0}", i.GetType().Name);
+ _logger.Info("Post-scan task cancelled: {0}", task.GetType().Name);
}
catch (Exception ex)
{
_logger.ErrorException("Error running postscan task", ex);
}
- }));
- await Task.WhenAll(tasks).ConfigureAwait(false);
+ numComplete++;
+ double percent = numComplete;
+ percent /= numTasks;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
}
///