aspnet / AspNetWebOptimization

ASP.NET Web Optimization for ASP.NET 4.x applications
15 stars 20 forks source link

Index was outside the bounds of the array - System.Web.Optimization.Bundle.UpdateCache #4

Closed shankargv87 closed 6 years ago

shankargv87 commented 6 years ago

Hi,

I'm getting the below bundling error when i testing the application using HPE LoadRunner.

I'm using the following version - Microsoft.AspNet.Web.Optimization 1.1.2, WebGrease.1.5.2, Microsoft.Web.Infrastructure.1.0.0.0

Issue 1: System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.List1.Add(T item) at System.Web.Optimization.Bundle.UpdateCache(BundleContext context, BundleResponse response) at System.Web.Optimization.Bundle.GetBundleResponse(BundleContext context) at System.Web.Optimization.BundleResolver.GetBundleContents(String virtualPath) at System.Web.Optimization.AssetManager.EliminateDuplicatesAndResolveUrls(IEnumerable1 refs) at System.Web.Optimization.AssetManager.RenderExplicit(String tagFormat, String[] paths) at Dss.Ivd.Pacss.Web.Common.CustomControl.PageBases.ScreenBase.OnInit(EventArgs e) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Issue 2: System.ArgumentNullException: Value cannot be null. Parameter name: key at System.Web.Caching.CacheKey..ctor(String key, Boolean isPublic) at System.Web.Caching.AspNetCache.Remove(String key, CacheItemRemovedReason reason) at System.Web.Optimization.Bundle.InvalidateCacheEntries() at System.Web.Optimization.BundleCollection.Add(Bundle bundle) at Dss.Ivd.Pacss.Web.Common.CustomControl.UIUtility.RenderScripts(String key, String[] filesList) at ASP.applicationsmemberdemographicsdemobankruptcyhistoryaspx.Rendercontrol1(HtmlTextWriter _w, Control parameterContainer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Page.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Please help me to resolve this issue.

Thanks

Eilon commented 6 years ago

This type of error is typically caused by the application modifying the list of bundles at runtime, which is not supported, and causes thread concurrency issues.

Please check that the application is not modifying the list of bundles outside of the startup logic.

shankargv87 commented 6 years ago

Hi,

I'm using the code like below

TestHistory.aspx <!DOCTYPE html> <html> <head runat="server"> <title /> </head> <body> <form id="frmTestHistory" runat="server"> </form> <%: UIUtility.RenderScripts( "TestHistory", new string[]{ "~/Applications/Test/TestHistory.js"} ) %> </body> </html>

UIUtility.cs

public static IHtmlString RenderScripts( string key, string[] filesList )
{
    string bundleKey = "~/js/" + key;

    System.Web.Optimization.BundleTable.Bundles.Add( new System.Web.Optimization.ScriptBundle( bundleKey )
      .Include( filesList ) );
    return System.Web.Optimization.Scripts.Render( bundleKey );
}

For this code i'm getting the "Issue 2" as i mentioned above.

Thanks

Eilon commented 6 years ago

Hi @shankargv87 , this behavior is not supported. It looks like this code is called outside of the Application_Start event. All bundles must be configured in App_Start and in no other place.

Closing this issue as by design.

shankargv87 commented 6 years ago

Hi,

Right now i'm using the code as i mentioned above to bundle the screen specific scripts. The issue is not occurring always. This is the first time i'm getting this issue when the testing the application using HPE load runner. Will it cause any performance issue when modifying the list of bundles outside of the startup logic.

Any other workaround to resolve this issue?

Thanks

Eilon commented 6 years ago

It is not supported to modify the list of bundles outside the startup logic. It's not a performance issue, it's a thread-safety issue. I'm not aware of any workaround, but you can try asking on https://stackoverflow.com. Thanks!

shankargv87 commented 6 years ago

Hi,

The below issue occurred when try to render (System.Web.Optimization.Scripts.Render("~/js/ab")) the bundled script which is not modified outside the startup logic. Could you please clarify why this error occurred?

Issue 1: System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.List1.Add(T item) at System.Web.Optimization.Bundle.UpdateCache(BundleContext context, BundleResponse response) at System.Web.Optimization.Bundle.GetBundleResponse(BundleContext context) at System.Web.Optimization.BundleResolver.GetBundleContents(String virtualPath) at System.Web.Optimization.AssetManager.EliminateDuplicatesAndResolveUrls(IEnumerable1 refs) at System.Web.Optimization.AssetManager.RenderExplicit(String tagFormat, String[] paths) at Dss.Ivd.Pacss.Web.Common.CustomControl.PageBases.ScreenBase.OnInit(EventArgs e) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Thanks

Eilon commented 6 years ago

@shankargv87 this type of error still looks like a threading issue. Are you sure there is no code in the application that modifies the list of bundles (or the contents of the bundles) while the app is running?

shankargv87 commented 6 years ago

Hi,

Yes, it is there. I will try to modify the code to avoid modifying the list of bundles at run-time.

Thank you for the clarification.

shankargv87 commented 6 years ago

Hi,

If i modify the code to register all the script in application_start it will affect the initial application startup time. I'm having around 85 script files to register in start up.

Is there any other way to do the on demand bundling?

Thanks

Eilon commented 6 years ago

Did you measure that it actually affects startup time? I wouldn't expect it to be slow. Please try it and see if it has any real effect.

shankargv87 commented 6 years ago

Hi,

As you suggested i moved all my script bundling to application start up. Still i'm getting the below error but not frequently. Any idea why this error still occurring ?

   at System.Collections.Generic.List`1.Add(T item)
   at System.Web.Optimization.Bundle.UpdateCache(BundleContext context, BundleResponse response)
   at System.Web.Optimization.Bundle.GetBundleResponse(BundleContext context)
   at System.Web.Optimization.BundleResolver.GetBundleContents(String virtualPath)
   at System.Web.Optimization.AssetManager.EliminateDuplicatesAndResolveUrls(IEnumerable`1 refs)
   at System.Web.Optimization.AssetManager.RenderExplicit(String tagFormat, String[] paths)
   at Dss.Ivd.Pacss.Web.Common.CustomControl.UIUtility.RenderScripts(String key, String[] filesList)
   at ASP.home_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Thanks

Eilon commented 6 years ago

What is the exception message?

shankargv87 commented 6 years ago

Index was outside the bounds of the array.

Eilon commented 6 years ago

@HaoK - any idea on this?

HaoK commented 6 years ago

This error doesn't look like its coming from ApplicationStart if its coming from ProcessRequestMain, the code is just a simple Add to a list that's failing which implies there's some concurrency going on.

I think its this line that's failing: https://github.com/aspnet/AspNetWebOptimization/blob/65e3911ffed89a5a24e15e593ae74fb0f4cd6cde/src/System.Web.Optimization/HttpContextCache.cs#L58

shankargv87 commented 6 years ago

Hi, How to avoid this error ? Any solution to resolve this error ?

shankargv87 commented 6 years ago

Hi,

Recently i found the below post. Is there anything i need to do with OutputCacheProfile?

========= https://archive.codeplex.com/?p=aspnetoptimization

Incompatibilities with VaryByCustom OutputCacheProfile

We currently are using an OutputCacheProfile that uses a VaryByCustom to vary the cached based on Request.Url.PathAndQuery which we need to do for our localisation to work. An HTTP Module does some pre-work to provide the page with some localisation information that doesn't show up in the end user URL (where standard URL routing then handles things). The number of cache variations is quite large (due to there being traffic from all countries in the world) and the traffic is very high as well.

The combination of all of this doesn't seem to be working very nicely with the Bundling and Minimisation of the Web Optimisation Framework. Essentially the CSS and JS doesn't need to change for each cache variation, but it appears that it is being redone each time a new cache variation comes along and during peak times we are seeing the following error come through many times (luckily we have a good static fallback in place which and so the user doesn't always know there was a problem)

Message: Exception of type 'System.Web.HttpUnhandledException' was thrown. Source: System.Web Target: HandleError Stack: at System.Web.UI.Page.HandleError(Exception e) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Inner Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.List1.Add(T item) at System.Web.Optimization.HttpContextCache.Put(BundleContext context, Bundle bundle, BundleResponse response) at System.Web.Optimization.Bundle.GetBundleResponse(BundleContext context) at System.Web.Optimization.BundleResolver.GetBundleContents(String virtualPath) at System.Web.Optimization.AssetManager.EliminateDuplicatesAndResolveUrls(IEnumerable1 refs) at System.Web.Optimization.AssetManager.DeterminePathsToRender(IEnumerable`1 assets) at System.Web.Optimization.AssetManager.RenderExplicit(String tagFormat, String[] paths) at ASP.masterpage_master.Rendercontrol2(HtmlTextWriter __w, Control parameterContainer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.HtmlControls.HtmlHead.RenderChildren(HtmlTextWriter writer) at System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) at ASP.masterpage_master.Rendercontrol1(HtmlTextWriter __w, Control parameterContainer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Page.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint).

I'm assuming there is some sort of incompatibility between the custom cache provider and the Web Optimisation Framework, but we are using the latest version (which other semi-related posts said we should do). Ideally though the Bundler should only be running if the files changed, so not sure why this is happening.

=========

Thanks