重写的抽象方法上的System.AccessViolationException

本文关键字:AccessViolationException System 抽象方法 重写 | 更新日期: 2023-09-27 18:28:01

有点困惑为什么我会遇到问题。我花了一段时间,但把这个问题分解为最简单的情况后,我出现了以下奇怪的行为(无论如何,在我看来)。

我有一个基类:

public abstract class FailedSubmitterBase
{
    public FailedSubmitterBase(UserApplicationToken userApplicationToken)
    {
    }
    public abstract int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails,
        string crmUsername, string crmSuperUsername);
}

和一个子实例:

public class CoreFailedSubmitter : FailedSubmitterBase
{
    private string _emptyNarrativeString = "Failed to post to CS - Unspecified Error";
    protected UserApplicationToken _userApplicationToken;
    public CoreFailedSubmitter(UserApplicationToken userApplicationToken) : base(userApplicationToken)
    {
        _userApplicationToken = userApplicationToken;
    }
        /**/
    public override int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails, string crmUsername, string crmSuperUsername)
    {
        return 0;
    }
}

当我这样称呼它时:

CoreFailedSubmitter failedSubmitter = new CoreFailedSubmitter(_userApplicationToken);
return failedSubmitter.ResubmitFailed(request, csItinerary, impersonatedUser, basketItem, crmResponseDetails, crmUsername, crmSuperUsername);

我得到System.AccessViolationException:

"试图读取或写入受保护的内存。这通常是指示其他内存已损坏。"

我已经在几台机器上复制了它(在调试时),所以我不认为这是实际的内存问题。

我不明白的是,如果我只是删除抽象方法,它会很好地工作例如:

public abstract class FailedSubmitterBase
{
    public FailedSubmitterBase(UserApplicationToken userApplicationToken)
    {
    }
 }

public class CoreFailedSubmitter : FailedSubmitterBase
{
    private string _emptyNarrativeString = "Failed to post to CS - Unspecified Error";
    protected UserApplicationToken _userApplicationToken;
    public CoreFailedSubmitter(UserApplicationToken userApplicationToken) : base(userApplicationToken)
    {
        _userApplicationToken = userApplicationToken;
    }
        /**/
    public int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails, string crmUsername, string crmSuperUsername)
    {
        return 0;
    }
}

为什么使用abstract方法会导致此异常失败?我看不出有什么原因。我错过了什么?

更新

通过稍微重新分解代码,我删除了abstract类,并用interface替换它。这是有效的。尽管interfaceabstract类在做同样的事情,但出于所有意图和目的。我真的不明白为什么会这样失败。对我来说唯一突出的是这个Access.CentralServices.CSService.Itinerary csItinerary类。这是一个自动生成的SOAP类,但同样,这只是一个普通的类,不是吗?

重写的抽象方法上的System.AccessViolationException

某些东西损坏了内存。当删除抽象类时,您没有看到这一点的原因是没有进行虚拟调用,因此不需要间接内存访问(指针)。

现在,是什么破坏了你的记忆?根据你的描述,考虑到这个问题总是可重复的,那么它就是确定性的。因此,在方法调用之前所做的一切都会破坏内存。我的猜测要么是你在这些类中做了什么,要么是为了构建这些类的对象:

UserApplicationToken 
ProviderRequest 
ImpersonatedUserDetails 
BasketItem 
CRMResponseDetails 

所以你应该小心观察它们。正如@usr在评论中所说,安全的CLR代码应该而不是产生访问冲突,所以要么您发现CLR/编译器有问题(VERY不太可能),要么您正在使用的某个类是罪魁祸首。另一种猜测是:这些令牌和模拟不会碰巧调用本机Win32库,是吗互操作与调用不安全代码相同。