![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
#3
| |||
| |||
|
|
Hello, I'm working on two bugs in my app. They seemed unrelated at first glance, but after some testing and searching the web for clues I am now sure they are somehow connected. The two pieces of code execute frequently, at regular intervals (this is a monitoring app) and sometimes - just sometimes, and I do mean seldom - exceptions are thrown.1. Invalid handle problem I have a typical unmanaged resource wrapper class which handles serial communication. I use p/invoke calls Create~ Read~ and WriteFile, I store handle to port in IntPtr member. It has destructor which closes the handle. It is disposable. Nothing out of ordinary. I check handles and status codes returned from those calls and when something goes wrong, I throw my exception with errcode from GetLastError() and formatted system error message. Typical. |
|
The code looks a bit like this: using (MyPInvokeSerialPort p = new MyPInvokeSerialPort)) { string s1 = p.Read(); // sometimes ex thrown here p.Write("sth"); // ...sometimes here string s2 = p.Read(); // ...and here // like i've said in most cases ex is not thrown at all } The exception contains "invalid handle" message. 2. Socket constructor problem In this case it's all NET. I sometimes ping somebody ![]() using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)) { // the exception is thrown in constructor! s.WhateverFunc1(); s.WhateverFunc2(); } The exception contains: "Socket operation on nonsocket"... which, I think, is socket's way of saying "invalid handle" I've read that Net.Socketsare mostly implemented by p/invoke over winsock2. These are two reasons I think the problems are connected. Then I've read also one or two articles about wierd - at first glance - GC behavior. It is also described in MSDN under "GC.KeepAlive" entry. So I've learned that when GC occurs and a local variable is no longer referenced in code, the object referenced by this variable MAY be freed (in my case finalized) by CG EVEN if the execution flow didn't leave current block. So for example: using (SomeDisposableAndFinalizableClass o = new SomeDisposableAndFinalizableClass()) { o.Whatever(); // o can be finalized here! SomeInstructionWithoutO(); SomeOtherInstructionWithoutO(); // o is already finalized } In case of my wrapper and I strongly suppose in case of a socket, finalization means closing the handle to resource. Any call to those objects would result in "invalid handle" exception. |
|
That is why I put GC.KeepAlive(p or socket) before end of using block in my code. I don't know if it fixed the problems yet. I don't suppose so. Because each piece of my code DOES REFERENCE the port or the socket almost to the end of using block. So GC should not mark my objects for cleanup. Also - the exception in socket's case is thrown in constructor! It's a long post, but a question is simple...anyone knows what may cause those problems? Thanks for all your help Jan |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |