You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET启动窗体与Module Main()的选择及资源提取优化问题

VB.NET 资源提取避免循环及Module Main()启动配置

一、资源提取代码的放置位置(避免循环)

你的代码出现循环是因为AssemblyResolve事件触发时,在事件处理函数内加载资源会再次触发该事件(资源加载过程中可能需要解析依赖),导致重复执行提取逻辑。解决核心是一次性提取资源并缓存,事件处理时直接使用缓存数据,推荐以下两种放置位置:

1. 窗体的Load事件(启用应用框架时)

窗体Load事件仅在启动时执行一次,适合提前提取并缓存资源:

' 定义缓存字典,存储资源字节数组
Private cachedAssemblies As New Dictionary(Of String, Byte())

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' 一次性提取所有资源到缓存
    cachedAssemblies.Add("name0", My.Resources.resname0)
    cachedAssemblies.Add("name1", My.Resources.resname1)
    cachedAssemblies.Add("name2", My.Resources.resname2)
End Sub

Private WithEvents domain As AppDomain = AppDomain.CurrentDomain
Private Function domainCheck(sender As Object, e As ResolveEventArgs) As Assembly Handles domain.AssemblyResolve
    ' 从缓存读取,避免重复提取和循环触发
    For Each kvp In cachedAssemblies
        If e.Name.Contains(kvp.Key) Then
            Return System.Reflection.Assembly.Load(kvp.Value)
        End If
    Next
    Return Nothing
End Function

2. 类的Shared构造函数(通用场景)

Shared构造函数在类第一次被访问时仅执行一次,无需依赖窗体事件:

' 静态缓存变量
Private Shared cachedAssemblies As Dictionary(Of String, Byte())

' Shared构造函数,仅执行一次
Shared Sub New()
    cachedAssemblies = New Dictionary(Of String, Byte()) From {
        {"name0", My.Resources.resname0},
        {"name1", My.Resources.resname1},
        {"name2", My.Resources.resname2}
    }
End Sub

Private WithEvents domain As AppDomain = AppDomain.CurrentDomain
Private Function domainCheck(sender As Object, e As ResolveEventArgs) As Assembly Handles domain.AssemblyResolve
    For Each kvp In cachedAssemblies
        If e.Name.Contains(kvp.Key) Then
            Return System.Reflection.Assembly.Load(kvp.Value)
        End If
    Next
    Return Nothing
End Function

二、使用Module Main()作为启动项的配置方法

可以使用Module Main()作为启动入口,需要关闭“应用框架”并手动配置:

配置步骤

  1. 右键项目 → 选择属性
  2. 切换到应用选项卡
  3. 取消勾选启用应用框架
  4. 在启动对象下拉菜单中,选择包含Sub Main()的模块(需提前创建该模块)

示例代码

Module MainModule
    Sub Main()
        ' 提前提取资源并缓存
        Dim cachedAssemblies As New Dictionary(Of String, Byte()) From {
            {"name0", My.Resources.resname0},
            {"name1", My.Resources.resname1},
            {"name2", My.Resources.resname2}
        }

        ' 绑定AssemblyResolve事件,直接使用缓存
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, Function(sender, e)
                                                               For Each kvp In cachedAssemblies
                                                                   If e.Name.Contains(kvp.Key) Then
                                                                       Return System.Reflection.Assembly.Load(kvp.Value)
                                                                   End If
                                                               Next
                                                               Return Nothing
                                                           End Function

        ' 启动主窗体(如果需要)
        Application.Run(New Form1())
    End Sub
End Module

内容的提问来源于stack exchange,提问作者genesis lubrigas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:46:36