Menu Control and System.InvalidOperationException: Collection was modified
<p>A few times a day, the following exception will be thrown from my Web Forms Application. The application has a master page that includes a menu. The exception is:</p>

<pre><code>01/10/13 23:57:10.481 ERROR 79 LonelyCache.Global - Exception occurred: 
System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---&gt; System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Web.UI.WebControls.MenuItemCollection.MenuItemCollectionEnumerator.MoveNext()
   at System.Web.UI.WebControls.Menu.MenuRendererStandards.RenderItems(HtmlTextWriter writer, Boolean staticOnly, MenuItemCollection items, Int32 level, Boolean needsAccessKey)
   at System.Web.UI.WebControls.Menu.MenuRendererStandards.RenderContents(HtmlTextWriter writer, Boolean staticOnly)
   at System.Web.UI.WebControls.Menu.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   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 ASP.geocacherpage_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\9b853d2b\87164de6\App_Web_qxpnvss5.10.cs:line 0
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)
</code></pre>

<p>The menu on the master page is the only menu so I presume the exception must be tied to it.</p>

<p>The exception implies that the menu was changed while it was being itereated through. The only code I have that changes the menu is to clear the menu then build it when the master page is loaded. At least that's my understanding.</p>

<p>This is an intermittent problem. That is, it only occurs a few times a day on a production site. I have seen where sometimes the menu isn't properly displayed (some items are missing). I presume that is a result of this exception occurring.</p>

<p>Does anyone have any ideas on what may cause this to occur?</p>

<p>Below is all the code I have that is associated with the menu.</p>

<p>From the Site.Master file:</p>

<pre><code>&lt;div class="menuSide"&gt;
    &lt;asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal" /&gt;
&lt;/div&gt;
</code></pre>

<p>From the Site.Master.cs file:</p>

<pre><code>public partial class SiteMaster : System.Web.UI.MasterPage
{
    private static readonly ILog log = LogManager.GetLogger(typeof(SiteMaster));

    public class NavMenu
    {
        private readonly bool anonymous;
        private readonly string role;
        private readonly MenuItem menuItem;

        public NavMenu(bool anon, string rol, MenuItem item)
        {
            anonymous = anon; role = rol; menuItem = item;
        }

        public bool Anonymous { get { return anonymous; } }
        public string Role { get { return role; } }
        public MenuItem Item { get { return menuItem; } }
    }

    static readonly NavMenu[] menu =
    {
        new NavMenu(true, null, new MenuItem("HOME", "", "", "~/")),
        new NavMenu(false, null, new MenuItem("PROFILE", "", "", "~/Account/Profile.aspx")),
        new NavMenu(true, null, new MenuItem("FORUM", "", "", "~/forum")),
        new NavMenu(true, null, new MenuItem("ABOUT", "", "", "~/About.aspx")),
        new NavMenu(false, "Administrators", new MenuItem("ADMIN", "", "", "~/Admin/Admin.aspx")),
    };

    private void buildMenu()
    {
        NavigationMenu.Items.Clear();

        foreach (var item in menu)
        {
            if (item.Anonymous ||
                (HttpContext.Current.User.Identity.IsAuthenticated &amp;&amp;
                 (item.Role == null || HttpContext.Current.User.IsInRole(item.Role))))
            {
                NavigationMenu.Items.Add(item.Item);
            }
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        buildMenu();
        // More stuff follows...
    }
}
</code></pre>
