How to recreate "Index was outside the bounds of the array" adding items to Dictionary?
Asked Answered
F

4

12

I'm consistenlty getting this error on a multithreading .net 3.5 application

ERROR 26 Exception thrown. Details: '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)

I think I know how to fix it (adding locks where appropiate) but I'd like to be able to recreate this problem on my local environment so I'll be sure that I fixed it and also I be able to add a unit test for it.

Do you know any consistent way to recreate this?

Frederik answered 5/10, 2012 at 14:19 Comment(2)
Is there a particular reason you're not using ConcurrentDictionary?Seamstress
@Sconibulus: this app is 3.5, can't use ConcurrentDictionary :(Frederik
Z
9
Dictionary<string, string> dict = new Dictionary<string, string>();

Task.Factory.StartNew(() => { while (true) dict["a"] = "a"; });
Task.Factory.StartNew(() => { while (true) dict.Remove("a"); });
Zemstvo answered 5/10, 2012 at 14:24 Comment(2)
Yes, this forces a dictionary error, but depending on the rest of the OP's code that is in play AND his proposed solution, this isn't exactly helpful.Dario
With this code I'm perfeclty able to recreate the problem, unfortunately can't say the same with my real code . Marking the question as resolved since I think this is the best I could get without throwing hundred of lines of code to the mix. Thanks!Frederik
D
4

Unfortunately, being consistent in a multithreaded application where race conditions occur is simply not achievable.

The hardware differences alone between your machine and the production one will ensure that when a problem does occur, it may not be in the same location. Even if the hardware is the same, software differences (especially those background services) can lead to timing differences and therefore a situation where it's just not repeatable.

Heck, if those threads have dependencies on external resources (like DB calls) the network latency differences between production and your test box might ensure that you can never duplicate it.

Shy of having a debugger on the server (bad bad idea), the best thing you can do is a visual analysis of the code, fix the parts you think need to be fixed, test it (as well as you can) then release and watch it in production.

Dario answered 5/10, 2012 at 14:22 Comment(0)
T
1

This won't help you to recreate the error locally, but to remove the error completely, the msdn docs for the generic Dictionary<TKey, TValue> say:

For a thread-safe alternative, see ConcurrentDictionary<TKey, TValue>.

The docs for ConcurrentDictionary<TKey, TValue> say:

Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently.

Note however, that ConcurrentDictionary<TKey, TValue> is only available in .Net 4 and up.

Triolein answered 5/10, 2012 at 14:27 Comment(1)
my app is 3.5, can't use ConcurrentDictionary :(Frederik
A
0

Why don't you create a wrapper for the Dictionary with a ReaderWriterLockSlim in it. That way you have all locking done in one class.

Alben answered 5/10, 2012 at 14:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.