c# System.AccessViolationException: Attempted to read or write protected memory.?

Anil Gadiyar picture Anil Gadiyar · Mar 17, 2017 · Viewed 11.6k times · Source

Not always but now and then i keep getting the below error, it doesn't effect me much "I think" but i would like to know the reason behind this and how i can solve it. i have tried disposing the context but i did not see any improvement. below is the error log i get.

      3/16/2017 7:06:55 AM ERROR IN PLM data into file System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Data.SqlServerCe.NativeMethods.CompileQueryPlan(IntPtr pQpCommand, String pwszCommandText, ResultSetOptions options, IntPtr[] pParamNames, IntPtr prgBinding, Int32 cDbBinding, IntPtr& pQpPlan, IntPtr pError)
   at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
   at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
   at System.Data.Entity.SqlServerCompact.SqlCeMultiCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass3.<GetResults>b__1()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at ILS.PLMOptimization.Algorithm.PLMOptimizationAlgorithm.Execute()

code here::

 [HandleProcessCorruptedStateExceptions]
        public bool Execute()
        {
            try
            {

                if (gridpst == true || gridpst == false)
                {
                    //gridpst = false; enable this if you want griddg true or false.

                    if (ADRFlag == true)
                    {
                        MsgBox = "DR EVENT RUNNING! Please wait";
                        Thread.Sleep(500);
                        MsgBox = null;


                    }
                    else if (ADRFlag == false)
                    {
                        //    #region startPlm

                        int calc_plm_data = 0;

                        DateTime my_date = DateTime.Now;  // get the present system time
                        int rem_min = my_date.Minute % 15;    // get the round off system time interms of 15 mintues...
                        int rem_sec = my_date.Second % 60;
                        DateTime my_startTime = my_date.AddMinutes(-rem_min);
                        my_startTime = my_startTime.AddSeconds(-rem_sec);
                        DateTime my_stopTime = my_date.AddMinutes(5 - rem_min);
                        my_stopTime = my_stopTime.AddSeconds(-rem_sec);

                        if (present_plm_data.peakStartTime <= DateTime.MinValue || present_plm_data.peakStopTime >= DateTime.MaxValue)
                        {
                            // first time it is entering this loop. Hence check the present datetime and fetch record from the database...
                            calc_plm_data = 1;
                        }
                        else if (DateTime.Now > present_plm_data.present_StopTime || DateTime.Now < present_plm_data.present_StartTime)
                        {   // present date and time are out of present peak data... so calculate a new peak data from the database
                            calc_plm_data = 1;
                        }

                        if (calc_plm_data == 1)
                        {
                            if (DbUpdateLoop.context.Database.Connection.State == System.Data.ConnectionState.Closed)
                                DbUpdateLoop.context.Database.Connection.Open();
                            //fetch collection
                            using (var context = Context.Create("C:\\XSR_BIB_V2\\XSR_BIB_V2_DATABASE.sdf", "", 4091))
                            {
                                if (DbUpdateLoop.context.Database.Connection.State == System.Data.ConnectionState.Closed)
                                    DbUpdateLoop.context.Database.Connection.Open();

                                try
                                {

                                    var data = DbUpdateLoop.context.EnergyPeakInfo_Tbl.Where(x => (my_startTime >= x.StartTime) && (my_stopTime <= x.StopTime)).FirstOrDefault();



                                    if (data == null)
                                    {
                                        MsgBox = "No data available in DB";
                                        Thread.Sleep(500);
                                        MsgBox = null;


                                        // data is not retrieved from the database, either the data is not present or database access return error
                                        // in this case, we need to get the data from the 
                                        return true;
                                    }

                                // get the peak data from the energyinfo...
                                present_plm_data.present_StartTime = my_startTime;
                                present_plm_data.present_StopTime = my_stopTime;
                                present_plm_data.peakStartTime = data.StartTime;
                                present_plm_data.peakStopTime = data.StopTime;
                                present_plm_data.peakType = data.PeakType;
                                present_plm_data.price = data.PricePerKW;
                                present_plm_data.threshHold = data.PlmThreshold;

                                //calculate the threshold value from the data available in database.
                                var startTS = new TimeSpan(my_startTime.Hour, my_startTime.Minute, my_startTime.Second);
                                var endTS = new TimeSpan(my_stopTime.Hour, my_stopTime.Minute, my_stopTime.Second);
                                if (noOfDaysToConsider == null)
                                    noOfDaysToConsider = 0;
                                noOfDaysToConsider = 1;
                                DateTime DaysToConsider = DateTime.Now.AddDays((-1) * noOfDaysToConsider).Date;

                                if (noOfDaysToConsider > 0)
                                {
                                    try
                                    {
                                        MsgBox = "Schedule  Number of days is greater than  0";
                                        Thread.Sleep(500);
                                        MsgBox = null;
                                        //it shld be  greater than or equal to

                                        if (DbUpdateLoop.context.Database.Connection.State == System.Data.ConnectionState.Closed)
                                            DbUpdateLoop.context.Database.Connection.Open();
                                        var allEntries = DbUpdateLoop.context.EnergyMeter_GridTbl.Where(x => x.Timestamp > DaysToConsider).ToArray();
                                        var entries = allEntries.Where(x => x.Timestamp.TimeOfDay >= startTS && x.Timestamp.TimeOfDay < endTS).ToArray();
                                        try
                                        {
                                            double avgKW = 0.2;//entries.Average(x => x.KW); //set as default uncoment when required.
                                            present_plm_data.threshHold = Math.Round(avgKW, 5);
                                            AVGTHRESHOLD = present_plm_data.threshHold;
                                        }
                                        catch (Exception ex)
                                        {
                                            // if no data is there in the data base, then make a default as per the xml file...
                                            MsgBox = "Schedule  Threshold no data is there in the data base, then make a default as per the xml file";
                                            Thread.Sleep(500);
                                            MsgBox = null;
                                            present_plm_data.threshHold = data.PlmThreshold;
                                            AVGTHRESHOLD = present_plm_data.threshHold;
                                            using (System.IO.StreamWriter file =
                                            new System.IO.StreamWriter(@"C:\XSR_BIB_V2\LOGFILE.txt", true))
                                            {
                                                // file.WriteLine(DateTime.Now + "Schedule  Threshold no data is there in the data base, then make a default as per the xml file " + ex);
                                            }
                                        }

                                    }
                                    catch (AccessViolationException aV)
                                    {   // if no data is there in the data base, then make a default as per the xml file...
                                        MsgBox = "Schedule  Threshold no data is there in the data base, then make a default as per the xml file";
                                        Thread.Sleep(500);
                                        MsgBox = null;
                                        present_plm_data.threshHold = data.PlmThreshold;
                                        AVGTHRESHOLD = present_plm_data.threshHold;
                                        using (System.IO.StreamWriter file =
                                        new System.IO.StreamWriter(@"C:\XSR_BIB_V2\LOGFILE.txt", true))
                                        {
                                            file.WriteLine(DateTime.Now + " ERROR IN PLM data into file " + aV);
                                        }
                                    }
                                    catch (Exception ee)
                                    {

                                    }
                                }
                                }
                                catch (AccessViolationException aV)
                                {
                                    using (System.IO.StreamWriter file =
                                        new System.IO.StreamWriter(@"C:\XSR_BIB_V2\LOGFILE.txt", true))
                                    {
                                        file.WriteLine(DateTime.Now + " ERROR IN PLM data into file " + aV);
                                    }
                                }
                                catch (Exception ee)
                                {

                                }
                            }
                        }

                        if (present_plm_data.peakType == 0)                     //Peak type = High  
                        {
                            //broadcast_Low = true;
                            //broadcast_Medium = true;
                            MsgBox = "Schedule TYPE 0 High Peak";
                            Thread.Sleep(500);
                            MsgBox = null;
                            firsttime_MidPeak = 0;
                            firsttime_OffPeak = 0;
                            AlgorithmForHighPeak(present_plm_data);
                            Thread.Sleep(3000);
                            Thread.Sleep(5000);
                        }
                        else if (present_plm_data.peakType == 1)                //Peak type = Medium
                        {
                            //broadcast_Low = true;
                            //broadcast_High = true;
                            MsgBox = "Schedule TYPE 1 Medium Peak";
                            Thread.Sleep(500);
                            MsgBox = null;
                            firsttime_OnPeak = 0;
                            firsttime_OffPeak = 0;
                            AlgorithmForMediumPeak(present_plm_data);
                            Thread.Sleep(3000);
                            Thread.Sleep(5000);
                        }
                        else if (present_plm_data.peakType == 2)                //Peak type = Low
                        {

                            MsgBox = "Schedule TYPE 2 Low Peak";
                            Thread.Sleep(500);
                            MsgBox = null;
                            firsttime_OnPeak = 0;
                            firsttime_MidPeak = 0;
                            AlgorithmForLowPeak(present_plm_data);
                            Thread.Sleep(3000);
                            Thread.Sleep(5000);
                        }
                        // }));



                    }



                }
                else if (gridpst == false)
                {
                    //switch to battery and break until grid is on 
                    MsgBox = "Schedule not running..";
                    Thread.Sleep(500);
                    MsgBox = null;

                }


            }
            catch (Exception ex)
            {
                MsgBox = " Schedule not running.due to unknown exception,please wait..";
                Thread.Sleep(500);
                MsgBox = null;
            }
            return true;
        }

Answer

Thiyagu Rajendran picture Thiyagu Rajendran · Mar 25, 2017

In .NET 4.0, the runtime handles certain exceptions raised as Windows Structured Error Handling (SEH) errors as indicators of Corrupted State. These Corrupted State Exceptions (CSE) are not allowed to be caught by your standard managed code. I won't get into the why's or how's here. Read this article about CSE's in the .NET 4.0 Framework:

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

But there is hope. There are a few ways to get around this:

Recompile as a .NET 3.5 assembly and run it in .NET 4.0.

Add a line to your application's config file under the configuration/runtime element: 
<legacyCorruptedStateExceptionsPolicy enabled="true|false"/>
Decorate the methods you want to catch these exceptions in with the HandleProcessCorruptedStateExceptions attribute available under `System.Runtime.ExceptionServices` namespace. 

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 for details.

For more reference: http://connect.microsoft.com/VisualStudio/feedback/details/557105/unable-to-catch-accessviolationexception