简体   繁体   English

更新数据时 RaisePropertyChanged 抛出 AccessViolationException

[英]RaisePropertyChanged throws AccessViolationException when update data

I was trying to update data through Textbox when click on the button the AccessViolationException throws out at random everytime I click on the button to execute some funtions Not just that,while executing the program,the application crash without throwing any exceptions(it happens at random too,and if I click on the button twice quickly,the application would crash 100%) What cause these problems and how to fix them?当我点击按钮时,我试图通过文本框更新数据,每次我点击按钮执行一些功能时,AccessViolationException 都会随机抛出不仅如此,在执行程序时,应用程序崩溃而没有抛出任何异常(它随机发生同样,如果我快速单击按钮两次,应用程序将崩溃 100%)导致这些问题的原因以及如何解决它们?

xaml: xml:

<Button Content="读取软件版本号" Command ="{Binding ReadSoftwareVersion}">
<Button Content="写入板号"  Command ="{Binding WriteMcuSNCommand}"/>
<Button Content="读取板号"  Command ="{Binding ReadMcuSNCommand}"/>
<TextBox Text="{Binding StrSW}" />
<TextBox Text="{Binding StrMCUSN}" />
<TextBox Text="{Binding StrWrite}" />

three Commands:三个命令:

private RelayCommand readSoftwareVersion;
public RelayCommand ReadSoftwareVersion
{
    get
    {
        readSoftwareVersion = new RelayCommand(ReadSW);
        return readSoftwareVersion;
    }
}

private RelayCommand writeMcuSNCommand;
public RelayCommand WriteMcuSNCommand
{
    get
    {
        writeMcuSNCommand = new RelayCommand(WriteMcuSN);
        return writeMcuSNCommand;
    }
}

private RelayCommand readMcuSNCommand;
public RelayCommand ReadMcuSNCommand
{
    get
    {
        readMcuSNCommand = new RelayCommand(ReadMcuSN);
        return readMcuSNCommand;
    }
}

And three functions:以及三个功能:

private void WriteMcuSN()
{

        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        byte[] NumberToWrite = new byte[11];
        NumberToWrite = System.Text.Encoding.Default.GetBytes(StrWrite);
        McuProtocolApi.funMcuWriteNumber(NumberToWrite, 10);
        McuProtocolApi.funMcuRelease();
}

private void ReadMcuSN()
{
        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        page = (byte)129;
        byte[] McuSN = new byte[10];
        McuProtocolApi.funMcuReadNumber(bank, page, McuSN, 10);
        McuProtocolApi.funMcuRelease();
        StrMCUSN = Encoding.Default.GetString(McuSN);

}

private void ReadSW()
{
        page = (byte)128;
        byte[] SoftwareVersion = new byte[12];
        McuProtocolApi.funMcuReadEEprom(bank, page, SoftwareVersion, 12);
        McuProtocolApi.funMcuRelease();
        StrSW = Encoding.Default.GetString(SoftwareVersion);

}

the McuProtocol is a DLL code in C++ and the declarations are: McuProtocol 是 C++ 中的 DLL 代码,声明如下:

   [DllImport("McuProtocol.dll")]
    public static extern int funMcuReadEEprom(byte bank, byte page, byte[] EEprom, int DataSize);

    [DllImport("McuProtocol.dll")]
    public static extern int funMcuReadNumber(byte bank, byte page, byte[] EEprom, int DataSize);

    [DllImport("McuProtocol.dll")]
    public static extern int funMcuWriteNumber(byte[] in_data, int DataSize);

PS:I don't think these two functions below are relevant, PS:我认为下面这两个功能不相关,

[DllImport("McuProtocol.dll")]
public static extern int funMcuRegister(int UartNum, int Baudrate); //this function opens a comport for transport bytes

[DllImport("McuProtocol.dll")]
public static extern int funMcuRelease();//this function releases comports

Edit:编辑:

I have optimized my code by replacing byte[] to IntPtr and the problems(both application crash and exception)still exist:我通过将 byte[] 替换为 IntPtr 来优化我的代码,并且问题(应用程序崩溃和异常)仍然存在:

    private void ReadSW()
    {
        page = (byte)128;
        string TransferStr = "";
        IntPtr SoftwareVersion;
        SoftwareVersion = Marshal.StringToCoTaskMemAuto(TransferStr);

        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        McuProtocolApi.funMcuReadEEprom(bank, page, SoftwareVersion, SoftwareVersionSize);
        McuProtocolApi.funMcuRelease();

        byte[] transfer = new byte[12];
        transfer = System.Text.Encoding.Unicode.GetBytes(Marshal.PtrToStringAuto(SoftwareVersion,SoftwareVersionSize/2));
        TransferStr = System.Text.Encoding.UTF8.GetString(transfer);

        StrSW = TransferStr;

    }

AccessViolationException is thrown when there is an attempt to read or write protected memory.尝试读取或写入受保护的内存时会引发 AccessViolationException。 You should be very careful when you trying to use a 3rd party C++ DLL.当您尝试使用第 3 方 C++ DLL 时,您应该非常小心。 Hence, I would recommend you to put some try-catch clause around these three Commands that you implemented.因此,我建议您在您实现的这三个命令周围放置一些 try-catch 子句。

Here are some helpful links: How to handle AccessViolationException以下是一些有用的链接: 如何处理 AccessViolationException

https://docs.microsoft.com/en-us/dotnet/api/system.accessviolationexception?view=net-6.0 https://docs.microsoft.com/en-us/dotnet/api/system.accessviolationexception?view=net-6.0

Edit: If you find that it is hard to catch the exception, try this: Step #1 - Add following snippet to config file编辑:如果您发现很难捕获异常,请尝试以下操作:步骤 #1 - 将以下代码段添加到配置文件

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>

Step #2第2步

Add添加

[HandleProcessCorruptedStateExceptions]
[SecurityCritical]

on the top of function you are tying catch the exception在您要绑定的函数的顶部捕获异常

(credit of EvilInside, How to handle AccessViolationException ) (EvilInside 的功劳, 如何处理 AccessViolationException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM