Re: Queue.Dequeue() causes exception "Object reference not set to an instance of an object."

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



newbie18 wrote:
Hi All,

I'm using almost the same approach as alexia in using Queue. However,
I'm not using any synchronize queue.

The sample code as follow has been running for about a year, but
recently I encounter "Object reference not set to an instance of an
object" error. Wondering would it be cause by the Queue. This error is
occurred at Process function in cSocket class. Please advise. [...]

I'm amazed the code worked at all.

The first thing it ought to do is throw an InvalidOperationException, due to trying to dequeue an element from an empty queue. Specifically: there is a very high likelihood of the receiving thread not getting a chance to execute, adding something to the queue, before the original thread gets into the cSocket.Process() method and tries to dequeue an item. And that's not even counting the likelihood of the receiving thread having to wait a bit for the first data to show up in the socket.

In other words, given the code shown, it should be quite common for the Process() method to attempt to dequeue data from the queue before the other thread has ever had a chance to enqueue any data. (And _that's_ not counting the lack of any synchronization/signaling, meaning that if the receiving thread _ever_ falls behind the original thread processing data, you should get an InvalidOperationException).

But even ignoring that issue, yes...you have no synchronization at all in your code, and so your use of the queue is just as unsynchronized as that found in alexia's code, and so can have the same problems, including dequeuing a null reference.

Due to the lack of synchronization, you also have other potential threading issues. For example, you have a class member, "socClient" that is not protected by any synchronization, but which is not initialized until the Listen() method starts to execute (and even there, not right away). You also have an endless loop in your receive thread, because you don't exit the loop when Receive() returns 0 (though, maybe you get an exception, I don't recall off the top of my head...not the best way to get out, but I suppose it's better than the thread hanging).

Basically, you've got multi-threaded code that hasn't got any proper synchronization or thread-safety at all.

And on top of all that, you're asking about VB.NET code in a C# newsgroup. :p

Pete
.



Relevant Pages

  • Re: thread-safety
    ... queue classes). ... consumer thread isn't going to do anything else, ... This Stopmethod doesn't interact with any of the synchronization you   ... waiting at a call to Monitor.Wait, because then the waiting thread would   ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: thread-safety
    ... but that would depend on the implementation of your Queue class. ... lock { ... It's odd for you to be passing a WaitHandle of any sort to the Monitor class; if you've got a WaitHandle, you would normally just wait on _that_, rather than using the WaitHandle simply as a synchronization object for Monitor. ... It would be a problem to call Monitor.Pulseif no other thread is waiting at a call to Monitor.Wait, because then the waiting thread would miss the Pulse. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Network Stack Locking
    ... coallescing of context switches to process multiple packets. ... therefore effective coallescing of synchronization. ... for example, if your stack trace in the ... TCP code only goes up to the queue receive primitive, ...
    (freebsd-arch)
  • Re: understanding: synchronized reference
    ... LinkedList queue = new LinkedList; ... public void put ... If queue should be accessed from multiple threads access needs to be synchronized. ... that in Java 1.5 there is are queue classes that has proper synchronization built in. ...
    (comp.lang.java.programmer)
  • Re: pthread_cond_wait and pthread_cond_signal
    ... I have a thread A that initialy finds a queue empty and therefore calls ... Why does it not wake up after T1 calls pthread_cond_signal?? ... You are inferring SCHEDULING based on SYNCHRONIZATION operations, and that's not what you should expect or what you should want. ... But one possible legitimate sequence of operations is this: you create 4 threads that will each immediately lock the mutex. ...
    (comp.programming.threads)