调用. submitchanges () linq时获得随机堆栈溢出

本文关键字:随机 堆栈 栈溢出 submitchanges linq 调用 | 更新日期: 2023-09-27 17:49:24

我得到一个stackoverflow异常时调用{DataContext}.SubmitChanges()…我希望我知道要发布哪些行代码来帮助澄清情况,但是异常在抛出时没有给出任何信息,它说:

An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

然后在View Detail中得到:

{Cannot evaluate expression because the current thread is in a stack overflow state.}

我已经在这个视图模型中查看了我的所有属性,以确保一切都被正确声明,并且没有问题导致那里的stackoverflow异常…它只发生在SubmitChanges()被调用之后。

下面是调用提交的代码:
public void VerifyAdvancePaymentsAndSave()
        {
            try
            {
                if (!VerifyTakeHomeActualBreakDownForAdvancePayments())
                {
                    MessageBox.Show(
                        "Cash, Check, and Money Order fields must add up to the amount in the Take Home Actual field!",
                        "Validation Error!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }
                if (MessageBox.Show("Are you sure you want to save this payment?", "Save", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                    return;
                if (!UserController.CreateUserController().CheckAccess(UserController.RestrictedAccessAction.EditCollections))
                {
                    return;
                }
                if (InitialCollectionAction == CollectionAction.ViewAdvancePayment)
                {
                    foreach (Advance a in Advances)
                    {
                        foreach (AdvancePayment ap in a.AdvancePayments)
                        {
                            AdvancePayment newAP = sp.AdvancePayments.Where(adv => adv.Id == ap.Id).SingleOrDefault();
                            if (newAP != null)
                            {
                                newAP.Payment = ap.Payment;
                                newAP.IsSaved = false;
                            }
                            else
                            {
                                MessageBox.Show("Could not find Advance Payment to apply amount to!");
                                return;
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        CurrentCollection.Status = BatchStatus.Open.ToString();
                        CurrentCollection.CollectionDate = DateTime.Now;
                        CurrentCollection.IsAdvancedPayment = true;
                        CurrentCollection.CollectionMachines = null;

                        //sp.Collections.InsertOnSubmit(CurrentCollection);
                    }
                    catch
                    {
                        MessageBox.Show("Error inserting changes!");
                    }
                }
                try
                {
                    sp.SubmitChanges();
                    if (InitialCollectionAction == CollectionAction.ViewAdvancePayment)
                        MessageBox.Show("Advance Payment was saved Successfully!");
                    else
                        MessageBox.Show("Advance Payment was submitted Sucessfully!");
                    CloseTab();
                }
                catch
                {
                    MessageBox.Show("Error submitting changes!");
                }
            }
            catch (Exception ex)
            {
                string message = UserController.CreateUserController().LoggedInUser.UserName + "'n" + ex.Message + "'n" + ex.StackTrace;
                EmailController.CreateEmailController().SendEmail("URM Error", message);
            }
        }

堆栈跟踪-在SubmitChanges()调用

之前
   at URM.ViewModels.CollectionsViewModel.VerifyAdvancePaymentsAndSave()
   at URM.Commands.CollectionsSaveCommand.Execute(Object parameter)
   at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at URM.App.Main()
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

这个视图模型中使用的模型:

public class AdvancePaymentsModel : INotifyPropertyChanged
    {
        public int AdvanceId { get; set; }
        public string PaymentId { get; set; }
        public decimal Payment { get; set; }
        public DateTime PaymentDate { get; set; }
        private string _status;
        public string Status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;
                OnPropertyChanged("Status");
            }
        }
        private Brush _brushObj;
        public Brush BrushObj
        {
            get
            {
                return _brushObj;
            }
            set
            {
                _brushObj = value;
                OnPropertyChanged("BrushObj");
            }
        }
        private AdvancePayment _advancePayment;
        public AdvancePayment AdvancePayment
        {
            get
            {
                return _advancePayment;
            }
            set
            {
                _advancePayment = value;
                OnPropertyChanged("AdvancePayment");
            }
        }
        private Visibility _voidButtonVisibility;
        public Visibility VoidButtonVisibility
        {
            get
            {
                return _voidButtonVisibility;
            }
            set
            {
                _voidButtonVisibility = value;
                OnPropertyChanged("VoidButtonVisibility");
            }
        }
}
public class AdvancePaymentsModel : INotifyPropertyChanged
    {
        public int AdvanceId { get; set; }
        public string PaymentId { get; set; }
        public decimal Payment { get; set; }
        public DateTime PaymentDate { get; set; }
        private string _status;
        public string Status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;
                OnPropertyChanged("Status");
            }
        }
        private Brush _brushObj;
        public Brush BrushObj
        {
            get
            {
                return _brushObj;
            }
            set
            {
                _brushObj = value;
                OnPropertyChanged("BrushObj");
            }
        }
        private AdvancePayment _advancePayment;
        public AdvancePayment AdvancePayment
        {
            get
            {
                return _advancePayment;
            }
            set
            {
                _advancePayment = value;
                OnPropertyChanged("AdvancePayment");
            }
        }
        private Visibility _voidButtonVisibility;
        public Visibility VoidButtonVisibility
        {
            get
            {
                return _voidButtonVisibility;
            }
            set
            {
                _voidButtonVisibility = value;
                OnPropertyChanged("VoidButtonVisibility");
            }
        }
     }
}

打开调试。net Framework源代码后…我看到stackoverflow异常在dispatcher类

中被抛出
 private void PushFrameImpl(DispatcherFrame frame) 
        {
            SynchronizationContext oldSyncContext = null;
            SynchronizationContext newSyncContext = null;
            MSG msg = new MSG(); 
            _frameDepth++; 
            try 
            {
                // Change the CLR SynchronizationContext to be compatable with our Dispatcher. 
                oldSyncContext = SynchronizationContext.Current;
                newSyncContext = new DispatcherSynchronizationContext(this);
                SynchronizationContext.SetSynchronizationContext(newSyncContext);
                try
                { 
                    while(frame.Continue) 
                    {
                        if (!GetMessage(ref msg, IntPtr.Zero, 0, 0)) 
                            break;
                        TranslateAndDispatchMessage(ref msg); //*<--------- gets thrown here*
                    } 
                    // If this was the last frame to exit after a quit, we 
                    // can now dispose the dispatcher. 
                    if(_frameDepth == 1)
                    { 
                        if(_hasShutdownStarted)
                        {
                            ShutdownImpl();
                        } 
                    }
                } 
                finally 
                {
                    // Restore the old SynchronizationContext. 
                    SynchronizationContext.SetSynchronizationContext(oldSyncContext);
                }
            }
            finally 
            {
                _frameDepth--; 
                if(_frameDepth == 0) 
                {
                    // We have exited all frames. 
                    _exitAllFrames = false;
                }
            }
        } 

在调度程序中崩溃后,这里是堆栈跟踪:

    [Managed to Native Transition]  
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Line 2281 + 0x35 bytes    Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Line 368 + 0x9 bytes  Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Line 327 + 0x34 bytes Unknown
>   PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Line 2745 C#
    PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Line 1841    C#
    PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) Line 261 + 0x9 bytes C#
    PresentationFramework.dll!System.Windows.Application.Run() Line 222 + 0x15 bytes    C#
    URM.exe!URM.App.Main() + 0x59 bytes C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x6b bytes    
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x27 bytes  
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x6f bytes   
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
    [Native to Managed Transition]  

所以在接受@KellyGendron和@David的建议后,我最终得到了在ChangeTracker类中抛出的stackoverflow异常

 internal override bool IsMemberPendingGeneration(MetaDataMember keyMember) {
                    if (this.IsNew && keyMember.IsDbGenerated) { 
                        return true;
                    }
                    // look for any FK association that has this key member (should only be one)
                    foreach (MetaAssociation assoc in type.Associations) { 
                        if (assoc.IsForeignKey) {
     /*CRASHES HERE*/      int index = assoc.ThisKey.IndexOf(keyMember); 
                            if (index > -1) { 
                                // we must have a reference to this other object to know if its side of
                                // the association is generated or not 
                                object otherItem = null;
                                if (assoc.ThisMember.IsDeferred) {
                                    otherItem = assoc.ThisMember.DeferredValueAccessor.GetBoxedValue(this.current);
                                } 
                                else {
                                    otherItem = assoc.ThisMember.StorageAccessor.GetBoxedValue(this.current); 
                                } 
                                if (otherItem != null) {
                                    if (assoc.IsMany) { 
                                        // Can't be pending generation for a value that would have to be the same
                                        // across many rows.
                                        continue;
                                    } 
                                    else {
                                        StandardTrackedObject trackedOther = (StandardTrackedObject)this.tracker.GetTrackedObject(otherItem); 
                                        if (trackedOther != null) { 
                                            MetaDataMember otherMember = assoc.OtherKey[index];
                                            return trackedOther.IsMemberPendingGeneration(otherMember); 
                                        }
                                    }
                                }
                            } 
                        }
                    } 
                    return false; 
                }
            } 
        }

关键成员似乎是从我可以从它的部分可用的属性是位置类(数据库表),它似乎被卡在ID列

调用. submitchanges () linq时获得随机堆栈溢出

我可能读错了你的代码,但是在这个片段中它看起来像newAP。支付将指向自身,这可能是严重混淆序列化器的原因。如果我读错了,再次原谅我,今天很缺觉。

foreach (AdvancePayment ap in a.AdvancePayments)
    {
        AdvancePayment newAP = sp.AdvancePayments
            .Where(adv => adv.Id == ap.Id).SingleOrDefault();
        if (newAP != null)
        {
            newAP.Payment = ap.Payment;
            ...

如果不是这种情况,您可能想尝试将保存分成多个部分,例如将关联设置为空,然后指定由ID。这里有一个类似的案例可能会有所帮助……http://social.msdn.microsoft.com/forums/silverlight/en us/d4438aaa a916 - 4335 - b182 ded75f162c2d/datacontextsubmitchanges抛出-堆栈溢出异常- -而不是简单插入

在做了很多事情之后-它最终成为一个问题,我的一个表有一个外键到它自己的主键。这导致了循环引用的发生。我发现调试这一点的最好方法是启用。net源代码的调试,然后我不得不在我的ViewModel中的OnPropertyChanged方法中放置一个断点。此时,我可以让异常在ChangeaTracker类中发生,否则它将在Dispatcher类中中断。