我有一个奇怪的问题导致我们出现问题。
我们有一个简单的C#Wpf UserControl。它是一个进度条 - 没什么特别的 - 只是根据与Value和MaxValue的绑定改变大小的边框。它可以在99%的时间内正常工作,我们在代码中的十几个地方使用它 - 包括启动画面。
它总是在启动画面中正常工作 - 所以它总是在我们的应用程序中加载和工作。
问题是有时(并且我们无法预测或理解何时)进度条构造函数中的InitializeComponent()调用会抛出System.Exception。查看在编译期间创建的progressbar.g.cs文件(obj / Debug文件夹)我可以看到抛出异常,因为找不到progressbar.xaml文件。当然,我没有更改g.cs文件中的任何代码,而且我在这个UserControl中根本没有做过任何想法。
System.Exception: The component 'MyProject.ControlLibrary.ProgressBar' does not have a resource identified by the URI '/MyProject.ControlLibrary;component/progressbar.xaml'.
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at MyProject.ControlLibrary.ProgressBar.InitializeComponent() in d:\Projectfolder\MyProject.ControlLibrary\ProgressBar.xaml:line 1
at MyProject.ControlLibrary.ProgressBar..ctor() in D:\projectfolder\MyProject.ControlLibrary\ProgressBar.xaml.cs:line 26
at ProjectName.UI.VideoViewer..ctor() in D:\projectfolder\UI\VideoViewer.xaml.cs:line 26
Source: PresentationFramework
我不明白为什么有时会丢失progressbar.xaml资源,特别是考虑到它在运行应用程序时至少可以运行一次。
UserControl包含在名为MyProject.ControlLibrary.dll的项目中。这个项目似乎配置正确,因为它包含其他没有显示任何问题的用户控件 - 除了另一个类似的UserControl有相同的问题。
我对此已经用尽了 - 所以任何建议都会有所帮助。我正在使用VisualStudio 2008和.net 3.5
答案 0 :(得分:2)
This Post 似乎是对问题的最佳讨论。简短的回答表明您的usercontrol可能已加载到两个不同的程序集中。很长的答案是,有很多人遇到了这个错误,并且不清楚他们是否找到了一致的解决方案/解决方法。有人说MS可能已经解决了4.0中的问题
答案 1 :(得分:2)
我可能已经解决了这个问题 - 我会在这里解释这个问题以防其他人遇到它。
我们代码的一部分动态加载插件文件夹中的插件。为此,它为plugins文件夹中的所有.dll文件执行Assembly.LoadFile(filename)。
它检查dll是否实现了我们的插件接口;如果它,它加载它,如果没有,它不加载它。我们的插件接口包含在名为MyProject.Interfaces.dll的文件中,此文件以及MyProject.ControlLibrary.dll也位于插件的文件夹中。
因此,代码有时会在MyProject.ControlLibrary.dll上调用Assembly.LoadFile两次,因为它循环遍历plugins文件夹中的dll。似乎在第二个LoadFile之后,xaml资源会丢失。当我阻止第二次加载时,似乎可以解决问题。
答案 2 :(得分:0)
我也想在这个主题上添加一些信息。
我也在使用插件式应用程序,每个程序集都加载在自己的AppDomain中,但首先我加载程序集以查看它是否以及我需要实例化的类。
为此我曾经使用过Assembly.Load(File.ReadAllBytes(file));
。如果我在实例化窗口之前这样做,那么InitializeComponent()
会把错误抛给我。
如果我首先实例化窗口然后加载程序集一切正常。 虽然可以随时打开和关闭窗口,因此大多数时候都会加载这些程序集。
我为解决此问题所做的工作是先创建一个单独的AppDomain,然后使用以下命令加载该appdomain中的程序集:Assembly asm = PrivateAssemblyLoader.Load(File.ReadAllBytes(file));
这样,当前的AppDomain不会受到加载的程序集的阻碍。
(在我的插件应用程序中,我在执行目录中查找所有.exe和.dll文件,因此它也可以加载自己。)