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

WPF调用类库本地化资源出现ObjectDisposedException问题

问题分析与解决方案

核心原因

你遇到的ObjectDisposedException: Cannot access a closed resource set异常,本质是LanguageProvider.GetSupportedLanguages()方法的实现错误释放了全局共享的本地化资源关联对象(比如ResourceManager或ResourceSet)。类库的Strings资源依赖全局存活的ResourceManager实例,一旦被提前释放,后续任何访问资源的操作都会触发该异常。

具体修改方案

1. 修正GetSupportedLanguages()的实现逻辑

绝对不要在方法中用using块包裹ResourceManager/ResourceSet,也不能手动调用Dispose()。正确的做法是通过读取附属程序集信息获取支持语言,而非直接操作并释放资源集。

示例修正代码:

public static IEnumerable<CultureInfo> GetSupportedLanguages()
{
    var assembly = typeof(LanguageProvider).Assembly;
    // 替换为你类库中Strings.resx的完整根名称(比如YourLibraryNamespace.Strings)
    var resourceBaseName = "YourLibraryNamespace.Strings";
    var resourceManager = new ResourceManager(resourceBaseName, assembly);

    var supportedCultures = new List<CultureInfo>
    {
        // 添加默认中性文化
        CultureInfo.InvariantCulture
    };

    var assemblyDir = Path.GetDirectoryName(assembly.Location);
    foreach (var dirPath in Directory.EnumerateDirectories(assemblyDir))
    {
        try
        {
            var cultureName = Path.GetFileName(dirPath);
            var culture = CultureInfo.GetCultureInfo(cultureName);
            // 验证该文化是否存在对应资源,不触发资源集的持久化释放
            if (resourceManager.GetResourceSet(culture, true, false) != null)
            {
                supportedCultures.Add(culture);
            }
        }
        catch (CultureNotFoundException)
        {
            // 跳过无效的文化目录
            continue;
        }
    }

    return supportedCultures;
}

注意:不要对resourceManager调用Dispose(),它需要保持全局可用以支持后续的资源访问。

2. 确认Strings资源的全局可用性

检查类库中由resx自动生成的Strings类,确保其ResourceManager属性是静态且未被手动修改/释放的。默认生成的代码如下,不要改动:

public static global::System.Resources.ResourceManager ResourceManager {
    get {
        if (object.ReferenceEquals(resourceMan, null)) {
            global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("YourLibraryNamespace.Strings", typeof(Strings).Assembly);
            resourceMan = temp;
        }
        return resourceMan;
    }
}

如果你的代码中存在Strings.ResourceManager.Dispose()这类操作,必须立即删除。

3. 调用时机调整(可选)

如果必须在MainWindow初始化前调用GetSupportedLanguages(),只需确保调用完成后不清理任何与本地化资源相关的对象即可,无需调整调用时机本身。

验证步骤

  1. 替换实现后重新编译整个解决方案
  2. 启动WPF项目,检查是否还会抛出ObjectDisposedException
  3. 测试界面本地化字符串加载、语言切换功能,确认资源访问正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:33:11