In .net core 3.1, on wpf we are getting a ridiculous number of missing resource file FileNotFoundException. I have read this is a part of normal processing. If the resource file
cannot be found and it will be searched for somewhere else why throw an exception which
has a huge processing time, why not return a result that says not found. We are getting these
exceptions constantly yet we still see our resource strings. Below is an example. The worst part is the same missing resource file FileNotFoundException get thrown multiple. The delays in program startup are very noticeable. If there is something that can be done to fix this I would appreciate it.
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Configuration.ConfigurationManager.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Configuration.ConfigurationManager.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Data.SqlClient.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Private.DataContractSerialization.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Private.DataContractSerialization.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.ComponentModel.Composition.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.ComponentModel.Composition.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Data.SqlClient.resources.dll
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll
Failed to resolve C:\Repository\GtNext\bin\Debug\System.Data.SqlClient.resources.dll
I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.
@dgxhubbard can you please provide the callstack for the exception? Attach a debugger, if it's Visual Studio please swithc of "just my code" and load symbols.
Tagging subscribers to this area: @tarekgh, @buyaa-n, @krwq
Notify danmosemsft if you want to be subscribed.
@dgxhubbard do you have a small sample to reproduce the issue so we can take a look? also, the stack trace will help too.
CC @ericstj
I am not sure where "Failed to resolve" comes from. I cannot find it in runtime/wpf/corefx/coreclr.
I think this properly a wpf issue but wanted to get repro first to confirm. @danmosemsft does it repro with any simple wpf app?
I have the debugger running. I will stop on the exception and get you a stack trace
We are running 3.1.3 and when we load our assemblies for MEF using code below, and with "Just My Code" disabled we get a FileNotFound exception even though the path and assembly name are correct. At that point we added an assembly resolver to try and clear up the problem. This is where the errors come from. We get System.Private.DataContractSerialization.resources, Version=4.1.5.0, Culture=en-US, PublicKeyToken=b03f5f7f11d50a3a as the argument name and then add "dll" to it to try and resolve. Which causes an exception when LoadFrom is called. If I turn on "Enable Just My Code" and disable the assembly resolver then all problems with loading our assemblies for MEF using code below disappear. I had forgotten about the problem with creating the assembly catalog.
Stack Trace
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
Assembly Resolver:
public BootstrapperBase ()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private Assembly CurrentDomain_AssemblyResolve ( object sender, ResolveEventArgs args )
{
Assembly assembly = null;
var name = args.Name;
var pos = name.IndexOf ( "," );
if ( pos != -1 )
{
name = name.Substring ( 0, pos );
}
name += ".dll";
var fullExeNameAndPath = Assembly.GetEntryAssembly ().Location;
var path = Path.GetDirectoryName ( fullExeNameAndPath );
var filepath = Path.Combine ( path, name );
try
{
assembly = Assembly.LoadFrom ( filepath );
}
catch ( Exception ex )
{
Debug.WriteLine ( "Failed to resolve " + filepath, ex );
LogProvider.Logger.LogException ( "Failed to resolve " + filepath, ex );
}
return assembly;
}
MEF Code to create assembly catalog:
`public static AssemblyCatalog GetCatalog( string assemblyName )
{
AssemblyCatalog assemblyCatalog = null;
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var codebase = assembly.GetName().CodeBase;
var path = codebase.Replace( @"file:///", string.Empty );
var basePath = System.IO.Path.GetDirectoryName( path );
var assemblyPath = Path.Combine( basePath, assemblyName );
try
{
assemblyCatalog = new AssemblyCatalog( assemblyPath );
}
catch ( Exception ex )
{
LogProvider.Logger.LogException( "Failed to load assembly catalog " + assemblyPath, ex );
}
return assemblyCatalog;
}`
This is the source of your exception:
var filepath = Path.Combine ( path, name );
try
{
assembly = Assembly.LoadFrom ( filepath );
}
catch ( Exception ex )
{
Debug.WriteLine ( "Failed to resolve " + filepath, ex );
LogProvider.Logger.LogException ( "Failed to resolve " + filepath, ex );
}
Perhaps you should do an exists check before calling Assembly.LoadFrom. Return null (fall through) if the file doesn't exist.
I would think the point of this is why is new AssemblyCatalog failing for something that exists. I admit that got buried because of the problem with exception.
Tagging subscribers to this area: @ViktorHofer
Notify danmosemsft if you want to be subscribed.
AssemblyCatelog at the end is calling Assembly.Load and Assembly.LoadFrom. Maybe the assembly trying to load is not listed in deps.json of the app which makes the loader not loading it? just a guess.
Since this is not a regression it's unlikely to make it in 5.0.0 due to the bar. Let's consider for 6.0.