Page 1 of 1

Simple Query causes IndexOutOfRangeException in dotConnect

Posted: Mon 15 Nov 2010 12:26
by mas
My application is a Workflow Service, where there are many instances running at the same time. Each time I make a query, I make a new ObjectContext and dispose of it after my query.

I spotted the following error in my application with the following stack trace:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.Dictionary`2.Resize()
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Devart.Data.Oracle.OracleTimeStamp.a()
at Devart.Data.Oracle.OracleTimeStamp..ctor(IntPtr A_0, OracleDbType A_1, ar A_2)
at Devart.Data.Oracle.l.m(Byte[] A_0, Int32 A_1, Int32 A_2)
at Devart.Data.Oracle.ad.g(Byte[] A_0, Int32 A_1, Int32 A_2)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at Query.QueryExecutor(DatabaseEntities context, Int64 executorId)
This error seems to be quite rare, as I've only seen it happen once out of thousands of test runs, and I am unable to reproduce it again. The query I run is quite simple:

Code: Select all

return (from e in context.Executors.Include("ExecutorType").Include("ExecutorState")
    where e.ExecutorId == executorId
    select e).FirstOrDefault();
Since this error is coming from the .NET Framework Dictionary object, I doubt this is a bug in the .NET Framework. Could this be a threading issue within the Devart library? As I mention above, I dispose the ObjectContext after each use, so there should be no threading issue from my application's perspective.

I am using Devart dotConnect for Oracle Professional 5.70.170.0.

Posted: Mon 15 Nov 2010 16:29
by AndreyR
We are investigating the situation.
If you are able to reproduce this error repeatedly, please send us a test project or at least describe the steps to reproduce it.

Posted: Thu 25 Nov 2010 11:30
by mas
Hi, is there any update on this issue?

I decided to take a look through reflector to see what's happening, as I ran into this problem again.

I have found that the Devart.Data.Oracle.OracleTimeStamp constructor calls a static method which initializes a static dictionary. The problem is, there is no locking mechanism for this initialization, so two threads are modifying the dictionary at the same time.

These static Dictionaries need to be initialized inside a lock, or initialized in the static constructor.

Posted: Thu 25 Nov 2010 12:21
by mas
I have created a workaround so that this threading issue won't appear.

I created a static constructor in the EntityModel, which calls the following code. This code will force the initialization of the static dictionaries in the OracleTimeStamp.

Code: Select all

private static volatile object _o;

_o = new Devart.Data.Oracle.OracleTimeStamp(2000, 01, 02, 03, 04, 05, 06, "Canada/Eastern", OracleDbType.TimeStampTZ);

Posted: Thu 25 Nov 2010 14:32
by AndreyR
Thank you for the feedback.
We have fixed the error, the upcoming release contains the fix.