Performance update

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti 2012-08-20 17:48:11 -04:00
parent 2c56e75ca5
commit 6fbeee841f
17 changed files with 179 additions and 173 deletions

View file

@ -22,7 +22,7 @@ namespace MediaBrowser.Common.UI
// Without this the app will shutdown after the splash screen closes // Without this the app will shutdown after the splash screen closes
this.ShutdownMode = ShutdownMode.OnExplicitShutdown; this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
await LoadKernel(); await LoadKernel().ConfigureAwait(false);
} }
private async Task LoadKernel() private async Task LoadKernel()

View file

@ -27,7 +27,7 @@ namespace MediaBrowser.Controller.FFMpeg
{ {
} }
await Run(item.Path, outputCachePath); await Run(item.Path, outputCachePath).ConfigureAwait(false);
using (FileStream stream = File.OpenRead(outputCachePath)) using (FileStream stream = File.OpenRead(outputCachePath))
{ {
@ -49,7 +49,7 @@ namespace MediaBrowser.Controller.FFMpeg
{ {
} }
await Run(item.Path, outputCachePath); await Run(item.Path, outputCachePath).ConfigureAwait(false);
using (FileStream stream = File.OpenRead(outputCachePath)) using (FileStream stream = File.OpenRead(outputCachePath))
{ {
@ -88,7 +88,7 @@ namespace MediaBrowser.Controller.FFMpeg
// If we ever decide to disable the ffmpeg log then you must uncomment the below line. // If we ever decide to disable the ffmpeg log then you must uncomment the below line.
process.BeginErrorReadLine(); process.BeginErrorReadLine();
await process.StandardOutput.BaseStream.CopyToAsync(stream); await process.StandardOutput.BaseStream.CopyToAsync(stream).ConfigureAwait(false);
process.WaitForExit(); process.WaitForExit();

View file

@ -42,13 +42,13 @@ namespace MediaBrowser.Controller
/// Gets the list of currently registered metadata prvoiders /// Gets the list of currently registered metadata prvoiders
/// </summary> /// </summary>
[ImportMany(typeof(BaseMetadataProvider))] [ImportMany(typeof(BaseMetadataProvider))]
public IEnumerable<BaseMetadataProvider> MetadataProviders { get; private set; } public BaseMetadataProvider[] MetadataProviders { get; private set; }
/// <summary> /// <summary>
/// Gets the list of currently registered entity resolvers /// Gets the list of currently registered entity resolvers
/// </summary> /// </summary>
[ImportMany(typeof(IBaseItemResolver))] [ImportMany(typeof(IBaseItemResolver))]
public IEnumerable<IBaseItemResolver> EntityResolvers { get; private set; } public IBaseItemResolver[] EntityResolvers { get; private set; }
/// <summary> /// <summary>
/// Creates a kernel based on a Data path, which is akin to our current programdata path /// Creates a kernel based on a Data path, which is akin to our current programdata path
@ -69,19 +69,19 @@ namespace MediaBrowser.Controller
{ {
await Task.Run(async () => await Task.Run(async () =>
{ {
await base.Init(progress); await base.Init(progress).ConfigureAwait(false);
progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 }); progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 });
ReloadUsers(); ReloadUsers();
progress.Report(new TaskProgress() { Description = "Extracting FFMpeg", PercentComplete = 20 }); progress.Report(new TaskProgress() { Description = "Extracting FFMpeg", PercentComplete = 20 });
await ExtractFFMpeg(); await ExtractFFMpeg().ConfigureAwait(false);
progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 }); progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 });
await ReloadRoot(); await ReloadRoot().ConfigureAwait(false);
progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 }); progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 });
}); }).ConfigureAwait(false);
} }
protected override void OnComposablePartsLoaded() protected override void OnComposablePartsLoaded()
@ -149,7 +149,7 @@ namespace MediaBrowser.Controller
DirectoryWatchers.Stop(); DirectoryWatchers.Stop();
RootFolder = await ItemController.GetItem(null, MediaRootFolderPath) as Folder; RootFolder = await ItemController.GetItem(null, MediaRootFolderPath).ConfigureAwait(false) as Folder;
DirectoryWatchers.Start(); DirectoryWatchers.Start();
} }
@ -168,17 +168,17 @@ namespace MediaBrowser.Controller
if (folder != null && folder.IsRoot) if (folder != null && folder.IsRoot)
{ {
await ReloadRoot(); await ReloadRoot().ConfigureAwait(false);
} }
else else
{ {
if (!Directory.Exists(item.Path) && !File.Exists(item.Path)) if (!Directory.Exists(item.Path) && !File.Exists(item.Path))
{ {
await ReloadItem(item.Parent); await ReloadItem(item.Parent).ConfigureAwait(false);
return; return;
} }
BaseItem newItem = await ItemController.GetItem(item.Parent, item.Path); BaseItem newItem = await ItemController.GetItem(item.Parent, item.Path).ConfigureAwait(false);
List<BaseItem> children = item.Parent.Children.ToList(); List<BaseItem> children = item.Parent.Children.ToList();
@ -238,7 +238,7 @@ namespace MediaBrowser.Controller
{ {
await Task.WhenAll( await Task.WhenAll(
providers.Select(i => i.Fetch(item, args)) providers.Select(i => i.Fetch(item, args))
); ).ConfigureAwait(false);
} }
// Second priority providers // Second priority providers
@ -248,7 +248,7 @@ namespace MediaBrowser.Controller
{ {
await Task.WhenAll( await Task.WhenAll(
providers.Select(i => i.Fetch(item, args)) providers.Select(i => i.Fetch(item, args))
); ).ConfigureAwait(false);
} }
// Third priority providers // Third priority providers
@ -258,7 +258,7 @@ namespace MediaBrowser.Controller
{ {
await Task.WhenAll( await Task.WhenAll(
providers.Select(i => i.Fetch(item, args)) providers.Select(i => i.Fetch(item, args))
); ).ConfigureAwait(false);
} }
// Lowest priority providers // Lowest priority providers
@ -268,7 +268,7 @@ namespace MediaBrowser.Controller
{ {
await Task.WhenAll( await Task.WhenAll(
providers.Select(i => i.Fetch(item, args)) providers.Select(i => i.Fetch(item, args))
); ).ConfigureAwait(false);
} }
// Execute internet providers // Execute internet providers
@ -278,7 +278,7 @@ namespace MediaBrowser.Controller
{ {
await Task.WhenAll( await Task.WhenAll(
providers.Select(i => i.Fetch(item, args)) providers.Select(i => i.Fetch(item, args))
); ).ConfigureAwait(false);
} }
} }
@ -289,8 +289,8 @@ namespace MediaBrowser.Controller
private async Task ExtractFFMpeg() private async Task ExtractFFMpeg()
{ {
// FFMpeg.exe // FFMpeg.exe
await ExtractFFMpeg(ApplicationPaths.FFMpegPath); await ExtractFFMpeg(ApplicationPaths.FFMpegPath).ConfigureAwait(false);
await ExtractFFMpeg(ApplicationPaths.FFProbePath); await ExtractFFMpeg(ApplicationPaths.FFProbePath).ConfigureAwait(false);
} }
private async Task ExtractFFMpeg(string exe) private async Task ExtractFFMpeg(string exe)
@ -305,7 +305,7 @@ namespace MediaBrowser.Controller
{ {
using (FileStream fileStream = new FileStream(exe, FileMode.Create)) using (FileStream fileStream = new FileStream(exe, FileMode.Create))
{ {
await stream.CopyToAsync(fileStream); await stream.CopyToAsync(fileStream).ConfigureAwait(false);
} }
} }
} }

View file

@ -57,12 +57,12 @@ namespace MediaBrowser.Controller.Library
} }
#endregion #endregion
private async Task<BaseItem> ResolveItem(ItemResolveEventArgs args) private BaseItem ResolveItem(ItemResolveEventArgs args)
{ {
// Try first priority resolvers // Try first priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.First)) foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.First))
{ {
var item = await resolver.ResolvePath(args); var item = resolver.ResolvePath(args);
if (item != null) if (item != null)
{ {
@ -73,7 +73,7 @@ namespace MediaBrowser.Controller.Library
// Try second priority resolvers // Try second priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Second)) foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Second))
{ {
var item = await resolver.ResolvePath(args); var item = resolver.ResolvePath(args);
if (item != null) if (item != null)
{ {
@ -84,7 +84,7 @@ namespace MediaBrowser.Controller.Library
// Try third priority resolvers // Try third priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Third)) foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Third))
{ {
var item = await resolver.ResolvePath(args); var item = resolver.ResolvePath(args);
if (item != null) if (item != null)
{ {
@ -95,14 +95,14 @@ namespace MediaBrowser.Controller.Library
// Try last priority resolvers // Try last priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Last)) foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Last))
{ {
var item = await resolver.ResolvePath(args); var item = resolver.ResolvePath(args);
if (item != null) if (item != null)
{ {
return item; return item;
} }
} }
return null; return null;
} }
@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.Library
/// </summary> /// </summary>
public async Task<BaseItem> GetItem(Folder parent, string path) public async Task<BaseItem> GetItem(Folder parent, string path)
{ {
return await GetItemInternal(parent, path, File.GetAttributes(path)); return await GetItemInternal(parent, path, File.GetAttributes(path)).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -154,14 +154,19 @@ namespace MediaBrowser.Controller.Library
return null; return null;
} }
BaseItem item = await ResolveItem(args); BaseItem item = ResolveItem(args);
var folder = item as Folder; if (item != null)
if (folder != null)
{ {
// If it's a folder look for child entities await Kernel.Instance.ExecuteMetadataProviders(item, args);
await AttachChildren(folder, fileSystemChildren);
var folder = item as Folder;
if (folder != null)
{
// If it's a folder look for child entities
await AttachChildren(folder, fileSystemChildren).ConfigureAwait(false);
}
} }
return item; return item;
@ -185,7 +190,7 @@ namespace MediaBrowser.Controller.Library
tasks[i] = GetItemInternal(folder, child.Key, child.Value); tasks[i] = GetItemInternal(folder, child.Key, child.Value);
} }
BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks); BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks).ConfigureAwait(false);
// Sort them // Sort them
folder.Children = baseItemChildren.Where(i => i != null).OrderBy(f => folder.Children = baseItemChildren.Where(i => i != null).OrderBy(f =>
@ -255,7 +260,7 @@ namespace MediaBrowser.Controller.Library
{ {
string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name); string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name);
return await GetImagesByNameItem<Person>(path, name); return await GetImagesByNameItem<Person>(path, name).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -265,7 +270,7 @@ namespace MediaBrowser.Controller.Library
{ {
string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name); string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name);
return await GetImagesByNameItem<Studio>(path, name); return await GetImagesByNameItem<Studio>(path, name).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -275,7 +280,7 @@ namespace MediaBrowser.Controller.Library
{ {
string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name); string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name);
return await GetImagesByNameItem<Genre>(path, name); return await GetImagesByNameItem<Genre>(path, name).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -285,7 +290,7 @@ namespace MediaBrowser.Controller.Library
{ {
string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString()); string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString());
return await GetImagesByNameItem<Year>(path, value.ToString()); return await GetImagesByNameItem<Year>(path, value.ToString()).ConfigureAwait(false);
} }
private ConcurrentDictionary<string, object> ImagesByNameItemCache = new ConcurrentDictionary<string, object>(); private ConcurrentDictionary<string, object> ImagesByNameItemCache = new ConcurrentDictionary<string, object>();
@ -301,7 +306,7 @@ namespace MediaBrowser.Controller.Library
// Look for it in the cache, if it's not there, create it // Look for it in the cache, if it's not there, create it
if (!ImagesByNameItemCache.ContainsKey(key)) if (!ImagesByNameItemCache.ContainsKey(key))
{ {
T obj = await CreateImagesByNameItem<T>(path, name); T obj = await CreateImagesByNameItem<T>(path, name).ConfigureAwait(false);
ImagesByNameItemCache[key] = obj; ImagesByNameItemCache[key] = obj;
return obj; return obj;
} }
@ -333,7 +338,7 @@ namespace MediaBrowser.Controller.Library
args.FileAttributes = File.GetAttributes(path); args.FileAttributes = File.GetAttributes(path);
args.FileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, FileAttributes>(f, File.GetAttributes(f))); args.FileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, FileAttributes>(f, File.GetAttributes(f)));
await Kernel.Instance.ExecuteMetadataProviders(item, args); await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false);
return item; return item;
} }

View file

@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Providers
string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
FFProbeResult data = await FFProbe.Run(audio, outputPath); FFProbeResult data = await FFProbe.Run(audio, outputPath).ConfigureAwait(false);
MediaStream stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase)); MediaStream stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));

View file

@ -25,7 +25,7 @@ namespace MediaBrowser.Controller.Providers
if (metadataFile.HasValue) if (metadataFile.HasValue)
{ {
await new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Key); await Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Key); }).ConfigureAwait(false);
} }
} }
} }

View file

@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Providers
foreach (string file in allFiles) foreach (string file in allFiles)
{ {
BaseItem child = await Kernel.Instance.ItemController.GetItem(null, file); BaseItem child = await Kernel.Instance.ItemController.GetItem(null, file).ConfigureAwait(false);
Video video = child as Video; Video video = child as Video;

View file

@ -43,7 +43,7 @@ namespace MediaBrowser.Controller.Providers
string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
FFProbeResult data = await FFProbe.Run(video, outputPath); FFProbeResult data = await FFProbe.Run(video, outputPath).ConfigureAwait(false);
} }
/// <summary> /// <summary>

View file

@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Resolvers
item.Id = Kernel.GetMD5(item.Path); item.Id = Kernel.GetMD5(item.Path);
} }
public async Task<BaseItem> ResolvePath(ItemResolveEventArgs args) public BaseItem ResolvePath(ItemResolveEventArgs args)
{ {
T item = Resolve(args); T item = Resolve(args);
@ -56,8 +56,6 @@ namespace MediaBrowser.Controller.Resolvers
// Make sure DateCreated and DateModified have values // Make sure DateCreated and DateModified have values
EnsureDates(item); EnsureDates(item);
await Kernel.Instance.ExecuteMetadataProviders(item, args);
} }
return item; return item;
@ -96,7 +94,7 @@ namespace MediaBrowser.Controller.Resolvers
/// </summary> /// </summary>
public interface IBaseItemResolver public interface IBaseItemResolver
{ {
Task<BaseItem> ResolvePath(ItemResolveEventArgs args); BaseItem ResolvePath(ItemResolveEventArgs args);
ResolverPriority Priority { get; } ResolverPriority Priority { get; }
} }

View file

@ -17,19 +17,19 @@ namespace MediaBrowser.Controller.Xml
/// <summary> /// <summary>
/// Fetches metadata for an item from one xml file /// Fetches metadata for an item from one xml file
/// </summary> /// </summary>
public async Task Fetch(T item, string metadataFile) public void Fetch(T item, string metadataFile)
{ {
// Use XmlReader for best performance // Use XmlReader for best performance
using (XmlReader reader = XmlReader.Create(metadataFile, new XmlReaderSettings() { Async = true })) using (XmlReader reader = XmlReader.Create(metadataFile, new XmlReaderSettings() { }))
{ {
await reader.MoveToContentAsync(); reader.MoveToContent();
// Loop through each element // Loop through each element
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
await FetchDataFromXmlNode(reader, item); FetchDataFromXmlNode(reader, item);
} }
} }
} }
@ -49,14 +49,14 @@ namespace MediaBrowser.Controller.Xml
/// <summary> /// <summary>
/// Fetches metadata from one Xml Element /// Fetches metadata from one Xml Element
/// </summary> /// </summary>
protected async virtual Task FetchDataFromXmlNode(XmlReader reader, T item) protected virtual void FetchDataFromXmlNode(XmlReader reader, T item)
{ {
switch (reader.Name) switch (reader.Name)
{ {
// DateCreated // DateCreated
case "Added": case "Added":
DateTime added; DateTime added;
if (DateTime.TryParse(await reader.ReadElementContentAsStringAsync() ?? string.Empty, out added)) if (DateTime.TryParse(reader.ReadElementContentAsString() ?? string.Empty, out added))
{ {
item.DateCreated = added; item.DateCreated = added;
} }
@ -65,7 +65,7 @@ namespace MediaBrowser.Controller.Xml
// DisplayMediaType // DisplayMediaType
case "Type": case "Type":
{ {
item.DisplayMediaType = await reader.ReadElementContentAsStringAsync(); item.DisplayMediaType = reader.ReadElementContentAsString();
switch (item.DisplayMediaType.ToLower()) switch (item.DisplayMediaType.ToLower())
{ {
@ -85,26 +85,26 @@ namespace MediaBrowser.Controller.Xml
// TODO: Do we still need this? // TODO: Do we still need this?
case "banner": case "banner":
item.BannerImagePath = await reader.ReadElementContentAsStringAsync(); item.BannerImagePath = reader.ReadElementContentAsString();
break; break;
case "LocalTitle": case "LocalTitle":
item.Name = await reader.ReadElementContentAsStringAsync(); item.Name = reader.ReadElementContentAsString();
break; break;
case "SortTitle": case "SortTitle":
item.SortName = await reader.ReadElementContentAsStringAsync(); item.SortName = reader.ReadElementContentAsString();
break; break;
case "Overview": case "Overview":
case "Description": case "Description":
item.Overview = await reader.ReadElementContentAsStringAsync(); item.Overview = reader.ReadElementContentAsString();
break; break;
case "TagLine": case "TagLine":
{ {
var list = (item.Taglines ?? new string[] { }).ToList(); var list = (item.Taglines ?? new string[] { }).ToList();
var tagline = await reader.ReadElementContentAsStringAsync(); var tagline = reader.ReadElementContentAsString();
if (!list.Contains(tagline)) if (!list.Contains(tagline))
{ {
@ -117,23 +117,23 @@ namespace MediaBrowser.Controller.Xml
case "TagLines": case "TagLines":
{ {
await FetchFromTaglinesNode(reader.ReadSubtree(), item); FetchFromTaglinesNode(reader.ReadSubtree(), item);
break; break;
} }
case "ContentRating": case "ContentRating":
case "MPAARating": case "MPAARating":
item.OfficialRating = await reader.ReadElementContentAsStringAsync(); item.OfficialRating = reader.ReadElementContentAsString();
break; break;
case "CustomRating": case "CustomRating":
item.CustomRating = await reader.ReadElementContentAsStringAsync(); item.CustomRating = reader.ReadElementContentAsString();
break; break;
case "Runtime": case "Runtime":
case "RunningTime": case "RunningTime":
{ {
string text = await reader.ReadElementContentAsStringAsync(); string text = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(text)) if (!string.IsNullOrWhiteSpace(text))
{ {
@ -149,20 +149,20 @@ namespace MediaBrowser.Controller.Xml
case "Genre": case "Genre":
{ {
var genres = (item.Genres ?? new string[] { }).ToList(); var genres = (item.Genres ?? new string[] { }).ToList();
genres.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|')); genres.AddRange(GetSplitValues(reader.ReadElementContentAsString(), '|'));
item.Genres = genres; item.Genres = genres;
break; break;
} }
case "AspectRatio": case "AspectRatio":
item.AspectRatio = await reader.ReadElementContentAsStringAsync(); item.AspectRatio = reader.ReadElementContentAsString();
break; break;
case "Network": case "Network":
{ {
var studios = (item.Studios ?? new string[] { }).ToList(); var studios = (item.Studios ?? new string[] { }).ToList();
studios.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|')); studios.AddRange(GetSplitValues(reader.ReadElementContentAsString(), '|'));
item.Studios = studios; item.Studios = studios;
break; break;
@ -171,7 +171,7 @@ namespace MediaBrowser.Controller.Xml
case "Director": case "Director":
{ {
var list = (item.People ?? new PersonInfo[] { }).ToList(); var list = (item.People ?? new PersonInfo[] { }).ToList();
list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Director" })); list.AddRange(GetSplitValues(reader.ReadElementContentAsString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Director" }));
item.People = list; item.People = list;
break; break;
@ -179,7 +179,7 @@ namespace MediaBrowser.Controller.Xml
case "Writer": case "Writer":
{ {
var list = (item.People ?? new PersonInfo[] { }).ToList(); var list = (item.People ?? new PersonInfo[] { }).ToList();
list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Writer" })); list.AddRange(GetSplitValues(reader.ReadElementContentAsString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Writer" }));
item.People = list; item.People = list;
break; break;
@ -189,19 +189,19 @@ namespace MediaBrowser.Controller.Xml
case "GuestStars": case "GuestStars":
{ {
var list = (item.People ?? new PersonInfo[] { }).ToList(); var list = (item.People ?? new PersonInfo[] { }).ToList();
list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Actor" })); list.AddRange(GetSplitValues(reader.ReadElementContentAsString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Actor" }));
item.People = list; item.People = list;
break; break;
} }
case "Trailer": case "Trailer":
item.TrailerUrl = await reader.ReadElementContentAsStringAsync(); item.TrailerUrl = reader.ReadElementContentAsString();
break; break;
case "ProductionYear": case "ProductionYear":
{ {
string val = await reader.ReadElementContentAsStringAsync(); string val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val)) if (!string.IsNullOrWhiteSpace(val))
{ {
@ -218,7 +218,7 @@ namespace MediaBrowser.Controller.Xml
case "Rating": case "Rating":
case "IMDBrating": case "IMDBrating":
string rating = await reader.ReadElementContentAsStringAsync(); string rating = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(rating)) if (!string.IsNullOrWhiteSpace(rating))
{ {
@ -233,7 +233,7 @@ namespace MediaBrowser.Controller.Xml
case "FirstAired": case "FirstAired":
{ {
string firstAired = await reader.ReadElementContentAsStringAsync(); string firstAired = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(firstAired)) if (!string.IsNullOrWhiteSpace(firstAired))
{ {
@ -250,7 +250,7 @@ namespace MediaBrowser.Controller.Xml
} }
case "TMDbId": case "TMDbId":
string tmdb = await reader.ReadElementContentAsStringAsync(); string tmdb = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(tmdb)) if (!string.IsNullOrWhiteSpace(tmdb))
{ {
item.SetProviderId(MetadataProviders.Tmdb, tmdb); item.SetProviderId(MetadataProviders.Tmdb, tmdb);
@ -258,7 +258,7 @@ namespace MediaBrowser.Controller.Xml
break; break;
case "TVcomId": case "TVcomId":
string TVcomId = await reader.ReadElementContentAsStringAsync(); string TVcomId = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(TVcomId)) if (!string.IsNullOrWhiteSpace(TVcomId))
{ {
item.SetProviderId(MetadataProviders.Tvcom, TVcomId); item.SetProviderId(MetadataProviders.Tvcom, TVcomId);
@ -268,7 +268,7 @@ namespace MediaBrowser.Controller.Xml
case "IMDB_ID": case "IMDB_ID":
case "IMDB": case "IMDB":
case "IMDbId": case "IMDbId":
string IMDbId = await reader.ReadElementContentAsStringAsync(); string IMDbId = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(IMDbId)) if (!string.IsNullOrWhiteSpace(IMDbId))
{ {
item.SetProviderId(MetadataProviders.Imdb, IMDbId); item.SetProviderId(MetadataProviders.Imdb, IMDbId);
@ -276,19 +276,19 @@ namespace MediaBrowser.Controller.Xml
break; break;
case "Genres": case "Genres":
await FetchFromGenresNode(reader.ReadSubtree(), item); FetchFromGenresNode(reader.ReadSubtree(), item);
break; break;
case "Persons": case "Persons":
await FetchDataFromPersonsNode(reader.ReadSubtree(), item); FetchDataFromPersonsNode(reader.ReadSubtree(), item);
break; break;
case "ParentalRating": case "ParentalRating":
await FetchFromParentalRatingNode(reader.ReadSubtree(), item); FetchFromParentalRatingNode(reader.ReadSubtree(), item);
break; break;
case "Studios": case "Studios":
await FetchFromStudiosNode(reader.ReadSubtree(), item); FetchFromStudiosNode(reader.ReadSubtree(), item);
break; break;
case "MediaInfo": case "MediaInfo":
@ -297,22 +297,22 @@ namespace MediaBrowser.Controller.Xml
if (video != null) if (video != null)
{ {
await FetchMediaInfo(reader.ReadSubtree(), video); FetchMediaInfo(reader.ReadSubtree(), video);
} }
break; break;
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
private async Task FetchMediaInfo(XmlReader reader, Video item) private void FetchMediaInfo(XmlReader reader, Video item)
{ {
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -320,7 +320,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Audio": case "Audio":
{ {
AudioStream stream = await FetchMediaInfoAudio(reader.ReadSubtree()); AudioStream stream = FetchMediaInfoAudio(reader.ReadSubtree());
List<AudioStream> streams = (item.AudioStreams ?? new AudioStream[] { }).ToList(); List<AudioStream> streams = (item.AudioStreams ?? new AudioStream[] { }).ToList();
streams.Add(stream); streams.Add(stream);
@ -330,59 +330,59 @@ namespace MediaBrowser.Controller.Xml
} }
case "Video": case "Video":
await FetchMediaInfoVideo(reader.ReadSubtree(), item); FetchMediaInfoVideo(reader.ReadSubtree(), item);
break; break;
case "Subtitle": case "Subtitle":
await FetchMediaInfoSubtitles(reader.ReadSubtree(), item); FetchMediaInfoSubtitles(reader.ReadSubtree(), item);
break; break;
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
} }
} }
private async Task<AudioStream> FetchMediaInfoAudio(XmlReader reader) private AudioStream FetchMediaInfoAudio(XmlReader reader)
{ {
AudioStream stream = new AudioStream(); AudioStream stream = new AudioStream();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
switch (reader.Name) switch (reader.Name)
{ {
case "Default": case "Default":
stream.IsDefault = await reader.ReadElementContentAsStringAsync() == "True"; stream.IsDefault = reader.ReadElementContentAsString() == "True";
break; break;
case "Forced": case "Forced":
stream.IsForced = await reader.ReadElementContentAsStringAsync() == "True"; stream.IsForced = reader.ReadElementContentAsString() == "True";
break; break;
case "BitRate": case "BitRate":
stream.BitRate = await reader.ReadIntSafe(); stream.BitRate = reader.ReadIntSafe();
break; break;
case "Channels": case "Channels":
stream.Channels = await reader.ReadIntSafe(); stream.Channels = reader.ReadIntSafe();
break; break;
case "Language": case "Language":
stream.Language = await reader.ReadElementContentAsStringAsync(); stream.Language = reader.ReadElementContentAsString();
break; break;
case "Codec": case "Codec":
stream.Codec = await reader.ReadElementContentAsStringAsync(); stream.Codec = reader.ReadElementContentAsString();
break; break;
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -391,42 +391,42 @@ namespace MediaBrowser.Controller.Xml
return stream; return stream;
} }
private async Task FetchMediaInfoVideo(XmlReader reader, Video item) private void FetchMediaInfoVideo(XmlReader reader, Video item)
{ {
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
switch (reader.Name) switch (reader.Name)
{ {
case "Width": case "Width":
item.Width = await reader.ReadIntSafe(); item.Width = reader.ReadIntSafe();
break; break;
case "Height": case "Height":
item.Height = await reader.ReadIntSafe(); item.Height = reader.ReadIntSafe();
break; break;
case "BitRate": case "BitRate":
item.BitRate = await reader.ReadIntSafe(); item.BitRate = reader.ReadIntSafe();
break; break;
case "FrameRate": case "FrameRate":
item.FrameRate = await reader.ReadElementContentAsStringAsync(); item.FrameRate = reader.ReadElementContentAsString();
break; break;
case "ScanType": case "ScanType":
item.ScanType = await reader.ReadElementContentAsStringAsync(); item.ScanType = reader.ReadElementContentAsString();
break; break;
case "Duration": case "Duration":
item.RunTimeTicks = TimeSpan.FromMinutes(await reader.ReadIntSafe()).Ticks; item.RunTimeTicks = TimeSpan.FromMinutes(reader.ReadIntSafe()).Ticks;
break; break;
case "DurationSeconds": case "DurationSeconds":
int seconds = await reader.ReadIntSafe(); int seconds = reader.ReadIntSafe();
if (seconds > 0) if (seconds > 0)
{ {
item.RunTimeTicks = TimeSpan.FromSeconds(seconds).Ticks; item.RunTimeTicks = TimeSpan.FromSeconds(seconds).Ticks;
@ -435,7 +435,7 @@ namespace MediaBrowser.Controller.Xml
case "Codec": case "Codec":
{ {
string videoCodec = await reader.ReadElementContentAsStringAsync(); string videoCodec = reader.ReadElementContentAsString();
switch (videoCodec.ToLower()) switch (videoCodec.ToLower())
{ {
@ -457,20 +457,20 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
} }
} }
private async Task FetchMediaInfoSubtitles(XmlReader reader, Video item) private void FetchMediaInfoSubtitles(XmlReader reader, Video item)
{ {
List<string> list = (item.Subtitles ?? new string[] { }).ToList(); List<string> list = (item.Subtitles ?? new string[] { }).ToList();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -478,7 +478,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Language": case "Language":
{ {
string genre = await reader.ReadElementContentAsStringAsync(); string genre = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(genre)) if (!string.IsNullOrWhiteSpace(genre))
{ {
@ -488,7 +488,7 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -497,13 +497,13 @@ namespace MediaBrowser.Controller.Xml
item.Subtitles = list; item.Subtitles = list;
} }
private async Task FetchFromTaglinesNode(XmlReader reader, T item) private void FetchFromTaglinesNode(XmlReader reader, T item)
{ {
List<string> list = (item.Taglines ?? new string[] { }).ToList(); List<string> list = (item.Taglines ?? new string[] { }).ToList();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -511,7 +511,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Tagline": case "Tagline":
{ {
string val = await reader.ReadElementContentAsStringAsync(); string val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val)) if (!string.IsNullOrWhiteSpace(val))
{ {
@ -521,7 +521,7 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -530,13 +530,13 @@ namespace MediaBrowser.Controller.Xml
item.Taglines = list; item.Taglines = list;
} }
private async Task FetchFromGenresNode(XmlReader reader, T item) private void FetchFromGenresNode(XmlReader reader, T item)
{ {
List<string> list = (item.Genres ?? new string[] { }).ToList(); List<string> list = (item.Genres ?? new string[] { }).ToList();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -544,7 +544,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Genre": case "Genre":
{ {
string genre = await reader.ReadElementContentAsStringAsync(); string genre = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(genre)) if (!string.IsNullOrWhiteSpace(genre))
{ {
@ -554,7 +554,7 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -563,13 +563,13 @@ namespace MediaBrowser.Controller.Xml
item.Genres = list; item.Genres = list;
} }
private async Task FetchDataFromPersonsNode(XmlReader reader, T item) private void FetchDataFromPersonsNode(XmlReader reader, T item)
{ {
List<PersonInfo> list = (item.People ?? new PersonInfo[] { }).ToList(); List<PersonInfo> list = (item.People ?? new PersonInfo[] { }).ToList();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -577,12 +577,12 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Person": case "Person":
{ {
list.Add(await GetPersonFromXmlNode(reader.ReadSubtree())); list.Add(GetPersonFromXmlNode(reader.ReadSubtree()));
break; break;
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -591,13 +591,13 @@ namespace MediaBrowser.Controller.Xml
item.People = list; item.People = list;
} }
private async Task FetchFromStudiosNode(XmlReader reader, T item) private void FetchFromStudiosNode(XmlReader reader, T item)
{ {
List<string> list = (item.Studios ?? new string[] { }).ToList(); List<string> list = (item.Studios ?? new string[] { }).ToList();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -605,7 +605,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Studio": case "Studio":
{ {
string studio = await reader.ReadElementContentAsStringAsync(); string studio = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(studio)) if (!string.IsNullOrWhiteSpace(studio))
{ {
@ -615,7 +615,7 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
@ -624,11 +624,11 @@ namespace MediaBrowser.Controller.Xml
item.Studios = list; item.Studios = list;
} }
private async Task FetchFromParentalRatingNode(XmlReader reader, T item) private void FetchFromParentalRatingNode(XmlReader reader, T item)
{ {
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
@ -636,7 +636,7 @@ namespace MediaBrowser.Controller.Xml
{ {
case "Value": case "Value":
{ {
string ratingString = await reader.ReadElementContentAsStringAsync(); string ratingString = reader.ReadElementContentAsString();
int rating = 7; int rating = 7;
@ -675,39 +675,39 @@ namespace MediaBrowser.Controller.Xml
} }
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }
} }
} }
private async Task<PersonInfo> GetPersonFromXmlNode(XmlReader reader) private PersonInfo GetPersonFromXmlNode(XmlReader reader)
{ {
PersonInfo person = new PersonInfo(); PersonInfo person = new PersonInfo();
await reader.MoveToContentAsync(); reader.MoveToContent();
while (await reader.ReadAsync()) while (reader.Read())
{ {
if (reader.NodeType == XmlNodeType.Element) if (reader.NodeType == XmlNodeType.Element)
{ {
switch (reader.Name) switch (reader.Name)
{ {
case "Name": case "Name":
person.Name = await reader.ReadElementContentAsStringAsync(); person.Name = reader.ReadElementContentAsString();
break; break;
case "Type": case "Type":
person.Type = await reader.ReadElementContentAsStringAsync(); person.Type = reader.ReadElementContentAsString();
break; break;
case "Role": case "Role":
person.Overview = await reader.ReadElementContentAsStringAsync(); person.Overview = reader.ReadElementContentAsString();
break; break;
default: default:
await reader.SkipAsync(); reader.Skip();
break; break;
} }
} }

View file

@ -11,9 +11,9 @@ namespace MediaBrowser.Controller.Xml
/// <summary> /// <summary>
/// Reads a float from the current element of an XmlReader /// Reads a float from the current element of an XmlReader
/// </summary> /// </summary>
public static async Task<float> ReadFloatSafe(this XmlReader reader) public static float ReadFloatSafe(this XmlReader reader)
{ {
string valueString = await reader.ReadElementContentAsStringAsync(); string valueString = reader.ReadElementContentAsString();
float value = 0; float value = 0;
@ -29,9 +29,9 @@ namespace MediaBrowser.Controller.Xml
/// <summary> /// <summary>
/// Reads an int from the current element of an XmlReader /// Reads an int from the current element of an XmlReader
/// </summary> /// </summary>
public static async Task<int> ReadIntSafe(this XmlReader reader) public static int ReadIntSafe(this XmlReader reader)
{ {
string valueString = await reader.ReadElementContentAsStringAsync(); string valueString = reader.ReadElementContentAsString();
int value = 0; int value = 0;

View file

@ -27,7 +27,7 @@ namespace MediaBrowser.Movies.Providers
if (metadataFile.HasValue) if (metadataFile.HasValue)
{ {
await new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Key); await Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Key); }).ConfigureAwait(false);
} }
} }
} }

View file

@ -8,13 +8,13 @@ namespace MediaBrowser.TV.Metadata
{ {
public class EpisodeXmlParser : BaseItemXmlParser<Episode> public class EpisodeXmlParser : BaseItemXmlParser<Episode>
{ {
protected override async Task FetchDataFromXmlNode(XmlReader reader, Episode item) protected override void FetchDataFromXmlNode(XmlReader reader, Episode item)
{ {
switch (reader.Name) switch (reader.Name)
{ {
case "filename": case "filename":
{ {
string filename = await reader.ReadElementContentAsStringAsync(); string filename = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(filename)) if (!string.IsNullOrWhiteSpace(filename))
{ {
@ -25,7 +25,7 @@ namespace MediaBrowser.TV.Metadata
} }
case "SeasonNumber": case "SeasonNumber":
{ {
string number = await reader.ReadElementContentAsStringAsync(); string number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number)) if (!string.IsNullOrWhiteSpace(number))
{ {
@ -36,7 +36,7 @@ namespace MediaBrowser.TV.Metadata
case "EpisodeNumber": case "EpisodeNumber":
{ {
string number = await reader.ReadElementContentAsStringAsync(); string number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number)) if (!string.IsNullOrWhiteSpace(number))
{ {
@ -46,11 +46,11 @@ namespace MediaBrowser.TV.Metadata
} }
case "EpisodeName": case "EpisodeName":
item.Name = await reader.ReadElementContentAsStringAsync(); item.Name = reader.ReadElementContentAsString();
break; break;
default: default:
await base.FetchDataFromXmlNode(reader, item); base.FetchDataFromXmlNode(reader, item);
break; break;
} }
} }

View file

@ -9,12 +9,12 @@ namespace MediaBrowser.TV.Metadata
{ {
public class SeriesXmlParser : BaseItemXmlParser<Series> public class SeriesXmlParser : BaseItemXmlParser<Series>
{ {
protected async override Task FetchDataFromXmlNode(XmlReader reader, Series item) protected override void FetchDataFromXmlNode(XmlReader reader, Series item)
{ {
switch (reader.Name) switch (reader.Name)
{ {
case "id": case "id":
string id = await reader.ReadElementContentAsStringAsync(); string id = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(id)) if (!string.IsNullOrWhiteSpace(id))
{ {
item.SetProviderId(MetadataProviders.Tvdb, id); item.SetProviderId(MetadataProviders.Tvdb, id);
@ -23,7 +23,7 @@ namespace MediaBrowser.TV.Metadata
case "Airs_DayOfWeek": case "Airs_DayOfWeek":
{ {
string day = await reader.ReadElementContentAsStringAsync(); string day = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(day)) if (!string.IsNullOrWhiteSpace(day))
{ {
@ -51,19 +51,19 @@ namespace MediaBrowser.TV.Metadata
} }
case "Airs_Time": case "Airs_Time":
item.AirTime = await reader.ReadElementContentAsStringAsync(); item.AirTime = reader.ReadElementContentAsString();
break; break;
case "SeriesName": case "SeriesName":
item.Name = await reader.ReadElementContentAsStringAsync(); item.Name = reader.ReadElementContentAsString();
break; break;
case "Status": case "Status":
item.Status = await reader.ReadElementContentAsStringAsync(); item.Status = reader.ReadElementContentAsString();
break; break;
default: default:
await base.FetchDataFromXmlNode(reader, item); base.FetchDataFromXmlNode(reader, item);
break; break;
} }
} }

View file

@ -34,7 +34,7 @@ namespace MediaBrowser.TV.Providers
string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".xml")); string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".xml"));
await FetchMetadata(episode, args.Parent as Season, metadataFile); await FetchMetadata(episode, args.Parent as Season, metadataFile).ConfigureAwait(false);
} }
private async Task FetchMetadata(Episode item, Season season, string metadataFile) private async Task FetchMetadata(Episode item, Season season, string metadataFile)
@ -56,7 +56,7 @@ namespace MediaBrowser.TV.Providers
} }
} }
await new EpisodeXmlParser().Fetch(item, metadataFile); await Task.Run(() => { new EpisodeXmlParser().Fetch(item, metadataFile); }).ConfigureAwait(false);
} }
} }
} }

View file

@ -27,7 +27,7 @@ namespace MediaBrowser.TV.Providers
if (metadataFile.HasValue) if (metadataFile.HasValue)
{ {
await new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Key); await Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Key); }).ConfigureAwait(false);
} }
} }
} }

View file

@ -76,4 +76,7 @@ Global
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal EndGlobal