簡體   English   中英

c# System.AccessViolationException:試圖讀取或寫入受保護的內存。?

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

並非總是如此,但有時我會不斷收到以下錯誤,“我認為”對我沒有太大影響,但我想知道這背后的原因以及如何解決它。 我曾嘗試disposing上下文,但沒有看到任何改進。 下面是我得到的錯誤日志。

      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()

代碼在這里::

 [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;
        }

在 .NET 4.0 中,運行時處理作為 Windows 結構化錯誤處理 (SEH) 錯誤引發的某些異常,作為損壞狀態的指標。 您的標准托管代碼不允許捕獲這些損壞狀態異常 (CSE)。 我不會討論這里的原因或方式。 閱讀有關 .NET 4.0 框架中 CSE 的這篇文章:

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

但有希望。 有幾種方法可以解決這個問題:

重新編譯為 .NET 3.5 程序集並在 .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了解詳情。

更多參考: http : //connect.microsoft.com/VisualStudio/feedback/details/557105/unable-to-catch-accessviolationexception

這個問題之前已經被很好地診斷出來,最好的辦法是閱讀你為“CompileQueryPlan AccessViolationException”獲得的谷歌點擊量。 這篇博文這個現有的 SO 問題是看起來最可靠的核心命中。 總之,之前確定了三個基本原因:

  1. .NET 提供程序與實現 SqlCompact 的本機 DLL 之間存在不匹配。 避免這種故障模式的最佳方法是使用Nuget 包,這樣您就擁有這些 DLL 的私有副本,並且可以確保不會出現 DLL Hell 問題。

  2. 在多個線程上運行 SQL 查詢。 任何 SQL 相關代碼都有可能出現的情況。 SqlCompact 不是線程安全的,需要鎖。

  3. 沒有設置 Connection 屬性。 這是 SO 問題中公認的答案。 從遠處看似乎不太可能是原因,用戶的代碼通過使用異步計時器肯定會圍繞原因 2 跳舞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM