Switching .dlls freezes application for way too long.
skowront opened this issue · 6 comments
The idea is simple. Suppose there are multiple libraries, each provides it's own localization resources and it's own windows.
Therefore:
xmlns:lexp="clr-namespace:WPFLocalizeExtension.Providers;assembly=WPFLocalizeextension"
lexp:ResxLocalizationProvider.DefaultAssembly="Project.Common.EntityFramework"
lexp:ResxLocalizationProvider.DefaultDictionary="SR"
is pretty common in code (with defaultassembly and defaultdictionary adjussted to each library of course).
So far so good, library works perfectly fine.
However InitializeComponent() function (not directly) calls the GetResourceManager function from ResxLocalizationProvicerBase.cs which is totally fine untill
// if no one was found, exception
if (resManager == null)
throw new ArgumentException(string.Format("No resource manager for dictionary '{0}' in assembly '{1}' found! ({1}.{0})", resourceDictionary, resourceAssembly));
// Add the ResourceManager to the cachelist
Add(resManKey, resManager);
try
{
// Look in all cultures and check available ressources.
foreach (var c in SearchCultures)
{
var rs = resManager.GetResourceSet(c, true, false);
if (rs != null)
AddCulture(c);
}
}
catch
{
// ignored
}
I am especially talking about this guy:
var rs = resManager.GetResourceSet(c, true, false);
He blocks the whole application for many seconds just to scroll through all available cultures. The GetResourceSet method is way to slow to use it like this. This bad boy throws many
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
and that is painfull for VisualStewdio
Usually no application provides all 768 cultures and oh boy, waiting for the application to throw all those exceptions is too long.
Personally, I could just make a join of SearchCultures and Directories in my assembly folder.
// Look in all cultures and check available ressources.
var assemblyDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
var directories = Directory.GetDirectories(assemblyDir);
var directoryNames = new List<string>();
foreach (var directory in directories)
{
directoryNames.Add(directory.Remove(0, Path.GetDirectoryName(directory).Length).Replace("\\",""));
}
var joined = new List<CultureInfo>();
foreach (var culture in SearchCultures)
{
if(directoryNames.Any(x=>x.ToLower()==culture.Name.ToLower()))
{
joined.Add(culture);
}
}
foreach (var c in joined)
{
var rs = resManager.GetResourceSet(c, true, false);
if (rs != null)
AddCulture(c);
}
The problem is only uncomfortable for a developper, without VisualStudio the problem is barely visible. I did not find any way to configure VisualStewdio to ignore those exceptions not only by not showing, but also by not handling them so the debugging session could speed up.
If my issue is redundant, please let me know, I'll remove it, but I did not find anywhere any usefull information about this lag, with proper analysis.
Hello! Sorry for really long answer.
@skowront, this problem appears when you Debug your application? Did you try to specify SearchCultures
yourself? If it works, I think this is the best solution.
As for me resManager.GetResourceSet
has really complicated logic and I affraid problems because of it. I think your solution (with some changes, because you shouldn't use Assembly.GetExecutingAssembly()
and handle if resources located at subdirectory) will work at 99.9% of cases, but I'm not sure if it's worth it.
Also I didn't have this problem working in VS. Probably it's because I have settings Just My Code
.
Yes, only while VS is attached to the process. When I run the application without VS there is no issue, and everything works seamlessly.
I would try to specify SearchCultures myself, yet i'm not aware how exactly (unless you just mean to hardcode it somewhere :D ).
Oops, yes, I offered to hardcode it. Sample:
WPFLocalizeExtension/tests/HelloWorldWPF/MainWindow.xaml.cs
Lines 37 to 44 in 788bbcb
But probably it's better to use
ResxLocalizationProvider.Instance.SearchCultures
directly and do it at App.xam.cs
Had I see this solutions earlier I wouldn't have opened this issue. However I'd say it does not seem a clean solution in terms of maintaining the code, but also totally valid.