"invalid handle", sockets, threads and garbage collector



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.Sockets are
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
.



Relevant Pages

  • Re: "invalid handle", sockets, threads and garbage collector
    ... your IntPtr value happens to coincide with a reference. ... The exception contains "invalid handle" message. ... Socket constructor problem ... finalization means closing the handle to resource. ...
    (microsoft.public.dotnet.framework.clr)
  • Re: TcpListener.Start error
    ... Yeah, I figured as much, but I'm having trouble getting back to that first ... after I get the first "Invalid argument" exception all ... I get is the "socket" exception, and I'm not exactly sure how to get it back ...
    (microsoft.public.dotnet.framework)
  • Re: TcpListener.Start error
    ... but at some point I get an "Invalid argument" exception. ... "...that is not a socket" when you call Start. ... You should be looking at, or at least posting and describing, the code that causes the "Invalid argument" error. ...
    (microsoft.public.dotnet.framework)
  • Re: An existing connection was forcibly closed by the remote host...
    ... EndReceivewill throw "Can't access disposed object" exception whenever the connection is terminated. ... In MS .NET Socket implementation there is no mechanism for the socket object to signal to the main thread that it is about to be disposed. ... public Socket ClientSocket ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: reconnect tcp
    ... instance throws a fatal exception, ... to close the socket and reconnect. ... public ClientHandler(Socket client, int timeout) ... while (rxDataCounter < receiveBytes) ...
    (microsoft.public.dotnet.languages.csharp)

Loading