'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?
xaml:
<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:
[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);
P.S.:I don't think these two functions below are relevant,
[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:
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;
}
Solution 1:[1]
AccessViolationException is thrown when there is an attempt to read or write protected memory. You should be very careful when you trying to use a 3rd party C++ DLL. Hence, I would recommend you to put some try-catch clause around these three Commands that you implemented.
Here are some helpful links: How to handle AccessViolationException
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
<configuration>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
</configuration>
Step #2
Add
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
on the top of function you are tying catch the exception
(credit of EvilInside, How to handle AccessViolationException)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
