davidwhitney / System.Configuration.Abstractions

Injectable, mockable, extensible, configuration for .NET
MIT License
42 stars 7 forks source link

"Source array was not long enough. Check srcIndex and length, and the array's lower bounds" #16

Closed roncanepa closed 6 years ago

roncanepa commented 6 years ago

I'm using custom converters to translate string values to an enum. I've noticed that every now and then I get the exception mentioned in the issue title. Most of the time, the code works just fine, and I'm wondering if it has to do with too many simultaneous requests.

I'm using v2.0.2.26.

Here's the stack trace when the exception happens in an ashx implementing IHttpHandler:

Stack Trace:
   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at System.Configuration.Abstractions.ConfigurationManager.RegisterTypeConverters(IConvertType[] converters) in c:\projects\system-configuration-abstractions\System.Configuration.Abstractions\ConfigurationManager.cs:line 38
   at project.name.Callback.ProcessRequest(HttpContext context) in C:\Users\username\Documents\working\library.name\project.name\Callback.ashx.cs:line 32
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

the usage in the ashx is:

        public void ProcessRequest(HttpContext context)
        {
            var wdsLogging= new Logging(13);
            var form = HttpContext.Current.Request.Form;

            var ourPlatformEnumConverter = new OurPlatformEnumConverter();
            var vendorPlatformEnumConverter = new vendorPlatformEnumConverter();
            ConfigurationManager.RegisterTypeConverters(ourPlatformEnumConverter, vendorPlatformEnumConverter );

and I've also had it happen every now and then in a webform page as well.

Do you have any thoughts on what might be causing it or how to fix it?

davidwhitney commented 6 years ago

My first thought is that the TypeConverters are a static collection, so you probably shouldn't be Registering a type converter on the start of each request, rather on application spin up.

That said - this shouldn't fail like that :)

I suspect you're bang on the money with the concurrency angle here - the implementation here just adds to a List, and lists aren't thread safe. I'll take a look and see if there's something I can do here.

davidwhitney commented 6 years ago

...in fact, now that my brain is working again - doing this will actually cause a memory leak in your application because it'll add an item to the internal List on each request. Definitely don't do this :)

davidwhitney commented 6 years ago

Version 2.0.2.39 fixes this issue - Added locking around Type Converter and Interceptor registration to deal with mulit-threaded use.

I still recommend you don't add type converters on each request as this is a static collection - prefer doing this at startup time.

roncanepa commented 6 years ago

Thank you for taking the time to investigate and patch in a fix for this.

I originally was doing the registration in startup events only, but then I ran into the problem in #13 and so started registering it per-request. I'll take another look and see if I can get it to work only in the startup.

davidwhitney commented 6 years ago

I'll take a look at #13 this evening too - apologies for the tardy replies to these issues!