预加载 .NET 程序集的好方法

发布于 2024-10-16 00:22:59 字数 340 浏览 1 评论 0原文

在我的应用程序中,我需要在鼠标单击时显示一个表单。问题在于该窗体位于另一个程序集中,并且由于程序集加载的惰性性质,当按下鼠标按钮时该程序集可能尚未加载。所以在表格最终出现之前我有一个非常明显的停顿。

我通过在初始化方法中调用 new FormFromAnotherAssembly() 来想出一个愚蠢的修复方法。当然,这解决了问题,停顿不再存在,但它非常丑陋。我喜欢这个解决方案的唯一一点是,我不必弄乱路径和程序集名称,如果我想使用像 Assembly.Load 这样的东西,我就必须这样做。

那么,如果我想确保在实际需要之前加载程序集,那么有什么好的、可靠的解决方案可供选择呢?

提前致谢。

In my app I need to show a form on mouse click. The problem is that the form is in another assembly and because of lazy nature of assembly loading it is likely that the assembly isn't loaded yet when the mouse button is pressed. So what I have is very noticeable pause before the form finally appears.

I was able to come up with a dumb fix by calling new FormFromAnotherAssembly() in my initialization method. That, of course, took care of things and the pause is no longer there, but it's very ugly. The only thing I like about this solution is that I don't have to mess with paths and assembly names which I have to do if I want to use something like Assembly.Load.

So, what's the good, robust solution of choice if I want to make sure the assembly is loaded before I actually need it?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

轮廓§ 2024-10-23 00:22:59

在 init 中显式预加载可能仍然是您的最佳选择。

typeof(SomeTypeFromAnotherAssembly) 应该足够了 - 以及一些无法优化的不透明方法;也许:

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));

这避免了new。请注意,这将加载,但不会进行 JIT 等。

如果您愿意,您可以在 BG 线程上执行此操作:

private static void LoadSomeStuff(object state) {
    GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
}
...
ThreadPool.QueueUserWorkItem(LoadSomeStuff);

Explicit pre-load in your init is probably still your best option.

a typeof(SomeTypeFromAnotherAssembly) should be enough - along with some opaque method that can't be optimised away; perhaps:

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));

This avoids the new. Note that this will be loaded, but not JITted etc.

If you wanted, you could do it on a BG thread:

private static void LoadSomeStuff(object state) {
    GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
}
...
ThreadPool.QueueUserWorkItem(LoadSomeStuff);
眼眸 2024-10-23 00:22:59

我相信 Assembly.Load 就是这样。

在应用程序启动期间,您应该找到模块、插件或任何其他运行时可插入的组件,并将它们的程序集加载到应用程序的域(AppDomain)中。

或者另一个更好的选择:为什么不使用控制反转呢?

您可以使用温莎城堡。假设您有 4 个要在运行时加载的表单,因此,您可以创建 4 个 Form 类的组件,它们的实现是要在程序生命周期中加载的 4 个表单。

如何使用这种方法进行预加载?您只需解决 Form 类型的所有依赖项/组件即可:

container.ResolveAll<Form>();

稍后您将获得一个特定的表单:

container.Resolve<Form>("CustomersForm"); // Just an example

如果您不知道控制反转,请注释掉,我会帮助您,没问题! :)

I believe that Assembly.Load is the way.

During application startup you should locate modules, plug-ins or any other run-time pluggable and load their assemblies into application's domain (AppDomain).

Or another and better option: Why don't you use inversion of control for that?

You can use Castle Windsor for that. Let's say you've 4 forms to load in run-time, so, you can create 4 components of Form class which their implementation are the 4 forms to load during the life-cycle of your program.

How to pre-load with this approach? You simply resolve all dependencies/components that are of type of Form and you got it:

container.ResolveAll<Form>();

Later you'll get a particular form:

container.Resolve<Form>("CustomersForm"); // Just an example

If you don't know inversion of control, comment out and I'll assist you, no problem! :)

别低头,皇冠会掉 2024-10-23 00:22:59

我认为最简单的方法是在 Assembly.Load() 中使用程序集名称:

System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");

您可以在 Visual Studio 中的引用属性下找到程序集名称:

Visual Studio 中的程序集名称

这样就可以避免输入 dll文件路径等。我用它来加速使用该 DLL 的对话框的加载速度。一旦程序主窗口完全加载,它就会启动一个仅调用 Assembly.Load() 的后台线程。当用户打开此对话框时,加载此 DLL 的小延迟就消失了。

I think that the easiest way is to just use the assembly name in Assembly.Load():

System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");

You can find the assembly name under the reference properties in Visual studio:

assembly name in visual studio

This way you can avoid entering dll file paths etc. I use this to speed up the loading of a dialog that uses this DLL. As soon as the program main window is fully loaded it launches a background thread that just calls Assembly.Load(). When the user opens this dialog the small lag of loading this DLL is gone.

乖乖哒 2024-10-23 00:22:59
var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));

这样可以吗?

var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));

Will that do?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文