Anyone have any clue as to why the hell
System.Collections.Generic.Dictionary could possibly
throw an exception of type IndexOutOfRangeException
This is what my event logger has recorded.
this is the exact section in the code.
tt being a string of value151: if (bNr) {
152: lock (sendlock)
153: Sent.Add(tt, 0);
154: }
4103-1
At that point there was 1 other element in the dictionary4103 is a sequential number that increments via this code
prior the code above.
int seq = Interlocked.Add(ref _seq, 1);
string tt = seq.ToString() + "-" + EndPointId;
Below is the exception !
Index was outside the bounds of the array.
-----------------
Stack: at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at RED.Net.Sockets.UdpSocket.Send(String message, Boolean bNr, Int32 timeout, IPEndPoint end, Boolean bHeader, Int32 EndPointId) in C:\Documents and Settings\Kasra\My Documents\Red Project\RED\RED.Net\UdpSocket.cs:line 153
-----------------
ToString: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at RED.Net.Sockets.UdpSocket.Send(String message, Boolean bNr, Int32 timeout, IPEndPoint end, Boolean bHeader, Int32 EndPointId) in C:\Documents and Settings\Kasra\My Documents\Red Project\RED\RED.Net\UdpSocket.cs:line 153
Kaz-

System.Collections.Generic.Dictionary(T(string), T(int)) throws Index was outside the bounds of the array !!????
Corvineum
This might be far fetched but I realized something.
While I'm adding an element within the Dictionary
the Add function might of been checking the hash
for an element while another asynchronous (thread)
might of been checking via ContainsKey and then
removing an element.
Thus it could of been a race- while Add function
was checking the dictionary for elements and
probably assumed that the dictionary would be
of size lets say 2 all of a sudden an element
was removed from another thread causing it
to throw an OutOfRangeException !!
Here's the code, I already know that this is a
problem and that I should of had a lock around this.
Another Thread !
if (msg == "OK")
{
if (Sent.ContainsKey(sp[0]))
Sent.Remove(sp[0]);
}
I am pretty confident this is the reason !
Kaz-
rebeccat
Hi,
I think you are correctly.
Based on my MSDN document about Dictionary Generic Class.
Thread Safety
Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.
Dictionary Generic Class
http://msdn2.microsoft.com/en-US/library/xfhwa508.aspx
So we need to implement our own threads synchronization when use the class.
e.g.
<pseudocode>
Dictionary d = new Dictionary();
Thread1Proc()
{
lock(d)
{
d.Add(a);
}
}
Thread2Proc()
{
lock(d)
{
d.Remove(a);
}
}
</pseudocode>
So that before every thread is trying to access to to the Dictionary, it needs to get a lock on the d first.
If you still have any concern, please feel free to post here.
Best regards,
Peter Huang
YCDC.CN
Hi
this replay not intended to solve the problem above, but rather to help any one who has found this thread because they are getting an IndexOutOfRangeException from a generic Queue.
As not locking your threads properly is not the only cause. Another cause is using TrimExcess and then using Enqueue later on.