1
I am in the final process of developing a program and I came across an error, I already spent some time researching and I could not solve the problem.
About the program:
In summary, the program receives and writes values in another program (Aspen HYSYS) and communicates with OPC servers writing and receiving values.
Some details to clarify more:
To update the values in the main form, I created 3 threads, one takes the values from the server and writes to the program, one takes the values from the program and writes to the server and the other has the first principle, as a secondary thread cannot change anything in the form interface, each thread makes an invoke calling a delegate to update the values in the program.
To communicate with OPC servers, I use two Softing DLL’s.
My problem:
When I give the command to update the values, the following error appears: "Attempt to read or write protected memory. This is often an idication that other memory is Corrupt.". From what I’ve researched, it’s like I’m trying to write in a memory space that’s already been displaced. Explicitly, I haven’t dislocated anything, but some Softing method may have misplaced or deleted the reference without me knowing.
The error does not happen on a specific line, it varies between read and write methods on the server.
Code snippet where the error happens:
if (opcform.plcopc.URL == null)
{
opcform.plcopc.URL = opcform.plcopc.getURL(opcform.GridExport.Rows[i].Cells[6].Value.ToString(),opcform.GridExport.Rows[i]Cells[7].Value.ToString());
//o método acima apenas pega a URL do servidor
opcform.plcopc.m_daSession = new DaSession(opcform.plcopc.URL);<<<<<<<<<<<<
//instancia uma sessão no servidor com a URL do mesmo
opcform.plcopc.m_daSubscription = new DaSubscription(500, opcform.plcopc.m_daSession); <<<<<<<<<
//instancia um objeto necessário para fazer as leituras e escritas de forma síncrona e adiciona ele a sessão
}
opcform.plcopc.m_daItem = new DaItem(opcform.GridExport.Rows[i].Cells[8].Value.ToString(), opcform.plcopc.m_daSubscription); <<<<<<<<<<<
opcform.plcopc.exOptions.ExecutionType = EnumExecutionType.SYNCHRONOUS;
//seta que a comunicação vai ser síncrona
if (opcform.plcopc.m_daSession.CurrentState != EnumObjectState.CONNECTED)
{
opcform.plcopc.m_daSession.Connect(true, true, opcform.plcopc.exOptions);
//conecta com o servidor
}
int retorno;
double vl = Convert.ToDouble(opcform.GridExport.Rows[i].Cells[4].Value);
//pega o valor que vai ser escrito no servidor
ValueQT vt = new ValueQT(vl, EnumQuality.GOOD, DateTime.Now);
//o objeto que vai ser escrito no servidor
opcform.plcopc.m_daItem.Write(vt, out retorno, opcform.plcopc.exOptions);<<<<<<
//escrevendo o objeto no servidor
Attempts:
Well, as they are in many lines the problem, I could not think of much, I tried to give a "lock" on some objects, but other errors appeared.
My request
Well, can someone tell me if there’s a way I can "block" the reference so only I can erase it? or how I can monitor to know where it is erased?
Please answer theoretically, you don’t need to enter thousands of lines of code and end up wasting your time. Materials so I can seek solution will be very welcome.
Give more details about and how the error occurs. This seems to be some problem of the Dlls you are using. O . Net doesn’t let you access the memory the way you want it. The code you presented doesn’t present any apparent problem. It is possible that some method called in it is doing what it should not. You use block
unsafe
somewhere in your code? This would be the only way to do something more abusive in memory. Other than that, it is the use of native resources that are out of control of the . Net that is causing the problem. Unless I remember something else.– Maniero
I only put an excerpt of the method, because it is great, what the method does is to take the information that is in a Datagrid view, that the user inserts, search the server(third line of the code that I showed), from there are things "standard" of the DLL to communicate with an OPC server (I think I described this well in the code), the problem is that I don’t have access to DLL, the only method created by me in the code above was geturl(). If the unsafe block is used, it is in the DLL, I did not use in my code. But you know if you have any way of knowing (some kind of debug) where the mess is being made?
– Jovita
I wondered if this might have been caused by the Garbage Collector, if it might have deleted some reference, is there any way I can block the GC from deleting certain things until my program is finished?
– Jovita
I agree with @bigown, I think you’re calling code Unmanaged, and you’re gonna have to use
GCHandle.Alloc
+GCHandleType.Pinned
to prevent GC from moving your objects while being used by Unmanaged code– dcastro
I’ll look into that and try to solve the problem with that, thank you
– Jovita
Do you have any material that can help me use these methods?
– Jovita
@Yanjovita I didn’t go too deep not, but in the searches I did on google, it seems to me that the problem doesn’t have much to do with the software (dll) itself, but with some patches applied on servers (especially .NET 3.5 or higher) in environments
Medium-Trust
and with certain drivers (Nvidea, Antivirus, etc). Many simply discovered the driver/software that was generating the error and took it out.. or moved to a Full Trust environment.– rodrigogq
I’m not sure I understand very well, you’re suggesting that it might be an external problem?
– Jovita
@Yanjovita yes I am. I will post here.
– rodrigogq
This error is looking like the external module has a BUG!
– lsalamon