1

作为前言,我查看了通过搜索此错误(其中 25 个左右)匹配的每个 StackOverflow 问题,但似乎都没有解决我遇到的问题。

我正在构建一个继承自 System.Windows.Form 的 PermissionsDialog。在调用的方法中,dialogPermissions.ShowDialog()我从数据库中检索一些 Role 对象并将它们加载到几个 ListBox 中。那工作得很好,但现在我需要使用这个伪代码过程覆盖我添加到列表框中的角色对象的属性之一:

  • 遍历角色列表
  • 使用从配置文件列表中查找匹配项List<T>.Find()
  • 在个人资料上查找属性
  • 建立一个新的角色并根据需要设置名称属性
  • 将角色添加到 PermissionsDialog 的角色列表

所有这一切都很顺利,但是当我调用dialogPermissions.ShowDialog()底层框架代码时会抛出 AccessViolationException。

这是我认为相关的代码:

List<UserProfile> userProfiles = new List<UserProfile>();
List<Role> allRoles = new List<Role>();
dialogData.AllRoles = new List<Role>();

using (var objectContext = this.SiteContext.CreateObjectContext())
{
    userProfiles = rs.UserProfiles.FindAll().ToList();
    allRoles = rs.Roles.FindAll();
}

foreach (Role role in allRoles.Where(role => role.BuiltInId == (int)BuiltInRoleId.UserProfileRole)) {
    var userProfile = userProfiles.Find(up => role.Id == up.Id);

    var roleToAdd = new Role {
        BuiltInId = role.BuiltInId,
        Description = role.Description,
        DirectoryEntry = role.DirectoryEntry,
        Id = role.Id,
        IsBuiltInRole = role.IsBuiltInRole,
        Name = null != profile ? profile.DisplayName:role.Name
    };
    dialogData.AllRoles.Add(roleToAdd);
}

我怀疑这在某种程度上是一个延迟执行问题,但ToList()在调用之前通过调用 dialogData.AllRoles来触发执行ShowDialog()并不能解决问题。当我用常量字符串替换 profile.DisplayName 时,我没有收到错误消息。

任何线索在这里的封面下发生了什么,或者如何找出正在发生的事情,或者如何以不同的方式解决问题以便我可以避免它?欢迎所有建议;-)

结论

所以这是实际的问题,我认为:

将 Role 的 Name 属性设置为 null 就可以了,但是当对话框尝试从 Role 创建 ListBoxItem 并将 Role.Name 属性用于 ListBoxItem 的 Content 属性(它是一个 Object)时,这不能设置为 null 并在构建对话框的框架代码中抛出。检查以确保我在那里有一个值可以解决问题。

似乎抛出一个奇怪的异常,但你有它......

4

2 回答 2

2

您测试 profile != null,但不测试 profile.DisplayName != null 所以这是从您的样本中首先想到的。

标准异常查找器是转到 Debug\Exceptions 并选中“抛出时中断”框,以便您可以看到抛出异常时的所有状态。

于 2012-09-20T16:33:31.977 回答
1

您可以盯着这段代码一周,却永远找不到 AccessViolationException 的原因。托管代码不会因像这样的处理器故障而死亡。

您需要从实际异常中挖掘出尽可能多的信息。这首先需要您启用非托管代码调试,以便您可以看到本机代码中的堆栈帧。项目+属性,调试选项卡,勾选“启用非托管代码调试”选项。

接下来,您要确保您拥有任何本机 Windows DLL 的 .pdb 文件。包括用于 Active Directory 的那些,在这种情况下有点可疑。工具 + 选项、调试、符号并启用 Microsoft 符号服务器。如果您有旧版本的 Visual Studio,它不能简单地单击复选框,请按 F1。

重现崩溃,调用堆栈应该很好地提示您怀疑什么本机代码。如果您无法解决问题,请将其发布在您的问题中。

于 2012-09-20T16:53:12.923 回答