Simple Query causes IndexOutOfRangeException in dotConnect

Simple Query causes IndexOutOfRangeException in dotConnect

Postby mas » Mon 15 Nov 2010 12:26

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.
mas
 
Posts: 25
Joined: Mon 15 Nov 2010 12:09

Postby AndreyR » Mon 15 Nov 2010 16:29

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.
AndreyR
Devart Team
 
Posts: 2919
Joined: Mon 07 Jul 2008 13:16

Postby mas » Thu 25 Nov 2010 11:30

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.
mas
 
Posts: 25
Joined: Mon 15 Nov 2010 12:09

Postby mas » Thu 25 Nov 2010 12:21

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);
mas
 
Posts: 25
Joined: Mon 15 Nov 2010 12:09

Postby AndreyR » Thu 25 Nov 2010 14:32

Thank you for the feedback.
We have fixed the error, the upcoming release contains the fix.
AndreyR
Devart Team
 
Posts: 2919
Joined: Mon 07 Jul 2008 13:16


Return to dotConnect for Oracle