使用DllImport代替较慢的Assembly.LoadFrom

3
我有几个资源DLL,目前在应用程序启动时使用以下代码加载:
Assembly ass = Assembly.LoadFrom(fi.FullName);
Type t = ass.GetTypes()[0];
string ns = t.Namespace;
BaseFacade bf = Activator.CreateInstance(t) as BaseFacade;
// bf.GoWild()...
当我拥有了BaseFacade后,就可以进行大量的函数调用以从DLL中获取资源,这一切都很好。然而,这个初始的LoadFrom非常缓慢,对于10个DLL,需要超过30秒。
因此,我想知道是否有替代方法?是否有任何方法?我想知道是否有可能做到这样:
[DllImport("myResources1.dll")]
public static extern void GoWild();
[DllImport("myResources2.dll")] public static extern void GoWild();
如果可能,如何公开那些资源DLL的GoWild函数?此外,考虑到这些DLL不总是位于主DLL的目录中(用户可以选择将这些DLL移动到其他位置),如何指向应用程序的DLL位置?
感谢您对此主题的任何建议!

1
你认真的吗?你把变量命名为 ass - Scott Smith
4
是的...我喜欢这样胡闹...例如我总是用:catch (SocketException sex) { }... - nikib3ro
3个回答

3

有一件事情可能会提高性能,那就是不要从已加载的程序集中检索所有类型。如果它们那么大(10 MB),我认为每个程序集中有很多类型Reflection需要处理。换句话说,去掉ass.GetTypes()调用,因为你显然只需要一个单独的类型。

顺便说一下,在返回的类型数组中访问第一个元素似乎有风险,因为Reflection不能保证返回类型的顺序。

相反,您可以定义一个程序集级别的自定义属性,指定应加载哪个继承自BaseFacade的类型。


这真是个绝妙的建议 - 我完全忽略了这个事实。然而,我刚刚进行了测试,因为每个程序集只有1种类型(其他全部是嵌入资源) - 一切都正常运行。我会查一下如何使用整个程序集级别的自定义属性...听起来很有趣。谢谢,伙计! - nikib3ro

2

通过你的第一个代码片段来看,你是通过反射加载.NET库。 DllImport 用于加载非托管库,而不是.NET程序集。

在没有更多了解该应用程序的知识的情况下,很难建议任何替代方法来完成你已经在做的事情。你可以在后台线程中使用第一个代码片段吗?


哼...所以想到DLLImport只是愚蠢的吗? :( 好吧,每天学习新东西。至于线程 - 我尝试在单独的线程中加载所有DLL,但似乎通过调用Assembly.LoadFrom同步线程,因为有某种锁定(在调试输出中,我可以看到DLL逐个加载)。 - nikib3ro

2

我认为这与DLL的大小有关 - 它们大约有10MB,加载一个需要大约3秒钟。考虑到我是在手机上完成所有这些操作,我想这个时间还可以接受... - nikib3ro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接