【问题标题】:Trace.Assert not breaking, neither showing the message boxTrace.Assert 不中断,也不显示消息框
【发布时间】:2010-12-17 22:43:06
【问题描述】:

我有一个 WPF 应用程序,我在其中在画布上移动数据。 当我像个怪物一样尝试用鼠标移动数据时,问题就开始了。

这是动作的顺序:

  • 画布上的 MouseMove 被触发
  • 在 MouseMove 中,我更改了一些数据
  • Trace.Assert 失败。调试器不会中断,消息框也不会中断
  • 触发了另一个 MouseMove
  • 数据再次更改
  • 由于集合中的重入检查而引发异常。调试器在那里中断。断言消息框从未显示。

这里最大的问题是我可以回到assert,但不是assert失败时的数据,而是最后修改的数据......所以基本上我无法正确调试。

这是堆栈跟踪,从第一个 MouseMove 开始(注意 ShowMessageBoxAssert 以及它仍在继续的事实......):

.Models.FCurve.MoveKey(int keyIndex = 3, double keyTime = 1182.0) 第 199 行 C# .Models.FCurve.KeyTimeChanged(Models.FCurveKey timeChangeKey = {Models.FCurveKey}) 第 186 行 + 0x2d 字节 C# .Models.FCurve.AddKeyToArray.AnonymousMethod(object sender = {Models.FCurveKey}, System.EventArgs args = {System.EventArgs}) 第 163 行 + 0x11 字节 C# [本机到托管转换] [管理到本地转换] .Models.FCurveKey.OnTimeChanged() 第 45 行 + 0x14 字节 C# .Models.FCurveKey..ctor.AnonymousMethod(object sender = {FCurveEditorTestApp.Impl.FCurveKeyImpl}, System.EventArgs args = {System.EventArgs}) 第 18 行 + 0x8 字节 C# [本机到托管转换] [管理到本地转换] FCurveEditorTestApp.exe!FCurveEditorTestApp.Impl.FCurveKeyImpl.OnTimeChanged() 第 43 行 + 0x14 字节 C# FCurveEditorTestApp.exe!FCurveEditorTestApp.Impl.FCurveKeyImpl.Time.set(double value = 1182.0) Line 34 + 0x8 bytes C# .Models.FCurveKey.Time.set(double value = 1182.0) 第 36 行 + 0x1b 字节 C# .ViewModels.CurveKeyViewModel.X.set(double value = 1182.0) 第 32 行 + 0x2b 字节 C# .ViewModels.CurveAreaViewModel.MoveSelectedItem.AnonymousMethod(ViewModels.CurveKeyViewModel key = {ViewModels.CurveKeyViewModel}) 第 127 行 + 0x2d 字节 C# Collections.CollectionHelper.ForEach(System.Collections.Generic.IEnumerable source = {System.Linq.Enumerable.OfTypeIterator}, System.Action action = {Method = {Void b__8(ViewModels.CurveKeyViewModel)}}) 第 31 行 + 0xe 字节 C# .ViewModels.CurveAreaViewModel.MoveSelectedItem(double deltaX = 693.0, double deltaY = 35.0) 第 126 行 + 0x63 字节 C# .Views.CurveAreaView._AreaCanvas_MouseMove(object sender = {System.Windows.Controls.Canvas}, System.Windows.Input.MouseEventArgs e = {System.Windows.Input.MouseEventArgs}) 第 195 行 + 0x2d 字节 C# PresentationCore.dll!System.Windows.Input.MouseEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x34 bytes PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate 处理程序,对象目标) + 0x27 字节 PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,System.Windows.RoutedEventArgs routedEventArgs) + 0x3e 字节 PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(对象源 = {System.Windows.Controls.Canvas},System.Windows.RoutedEventArgs args = {System.Windows.Input.MouseEventArgs},bool reRaised = false)+ 0x1bf 字节 PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender = {System.Windows.Controls.Canvas},System.Windows.RoutedEventArgs args = {System.Windows.Input.MouseEventArgs})+ 0x79 字节 PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args = {System.Windows.Input.MouseEventArgs}, bool trust) + 0x35 字节 PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x311 字节 PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs 输入) + 0x42 字节 PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 字节 PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode 模式, int 时间戳, System.Windows.Input.RawMouseActions 动作, int x, int y, int wheel) + 0x2e2 字节 PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd = 2628604,int msg = 512,System.IntPtr wParam = 1,System.IntPtr lParam = 30409804,ref bool 处理 = false)+ 0x22b 字节 PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd = 2628604,int msg = 512,System.IntPtr wParam = 1,System.IntPtr lParam = 30409804,ref bool 处理 = false)+ 0x75 字节 WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = 2628604,int msg = 512,System.IntPtr wParam = 1,System.IntPtr lParam = 30409804,ref bool 处理 = false)+ 0xbe 字节 WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x7a 字节 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate 回调 = {Method = {System.Object DispatcherCallbackOperation(System.Object)}},对象 args = {MS.Win32.HwndSubclass.DispatcherOperationCallbackParameter},bool isSingleParameter = true) + 0x8a 字节 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate 回调, object args, bool isSingleParameter, System.Delegate catchHandler = null) + 0x4a 字节 WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegate 回调,对象 args,bool isSingleParameter,System.Delegate catchHandler) + 0x44 字节 WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority 优先级, System.TimeSpan 超时, System.Delegate 方法, 对象参数, bool isSingleParameter) + 0x91 字节 WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority 优先级,System.Delegate 方法,对象 arg) + 0x40 字节 WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = 2628604, int msg = 512, System.IntPtr wParam = 1, System.IntPtr lParam = 30409804) + 0xdc 字节 [本机到托管转换] [管理到本地转换] System.dll!System.Diagnostics.AssertWrapper.ShowMessageBoxAssert(string stackTrace, string message, string detailMessage) + 0x103 字节 System.dll!System.Diagnostics.DefaultTraceListener.Fail(字符串消息,字符串detailMessage)+ 0xb2字节 System.dll!System.Diagnostics.DefaultTraceListener.Fail(字符串消息)+ 0xa 字节 System.dll!System.Diagnostics.TraceInternal.Fail(string message = "") + 0xb6 bytes System.dll!System.Diagnostics.Trace.Assert(布尔条件)+ 0x1c 字节 .ViewModels.CurvePathViewModel.CurvePathViewModel(Models.FCurveKey startKey = {Models.FCurveKey}, Models.FCurveKey endKey = {Models.FCurveKey}, ViewModels.IInterpolationProvider interpolatorProvider = {ViewModels.InterpolationInfoProvider}) 第 29 行 + 0x4e 字节 C# .ViewModels.CurvePathViewModel.CurvePathViewModel(ViewModels.CurveKeyViewModel startKey = {ViewModels.CurveKeyViewModel}, ViewModels.CurveKeyViewModel endKey = {ViewModels.CurveKeyViewModel}, ViewModels.IInterpolationProvider interpolatorProvider = {ViewModels.InterpolationInfoProvider}) 第 20 行 + 0x81 字节 C# .ViewModels.CurveViewModel.UpdateSegmentForKey(ViewModels.CurveKeyViewModel key = {ViewModels.CurveKeyViewModel}) 第 215 行 + 0x41 字节 C# .ViewModels.CurveViewModel.KeyViewModelsChanged(object sender = Count = 13, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) 第 187 行 + 0x30 字节 C# [本机到托管转换] [管理到本地转换] WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0x50 字节 WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedAction action, object item, int index, int oldIndex) + 0x34 bytes WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.MoveItem(int oldIndex, int newIndex) + 0x6f 字节 WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.Move(int oldIndex, int newIndex) + 0xe 字节 Collections.CollectionSynchronizer._SourceList_CollectionChanged(object sender = Count = 13, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) 第 239 行 + 0x45 字节 C# [本机到托管转换] [管理到本地转换] WindowsBase.dll!System.Collections.ObjectModel.ReadOnlyObservableCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x1d 字节 WindowsBase.dll!System.Collections.ObjectModel.ReadOnlyObservableCollection.HandleCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0xe 字节 [本机到托管转换] [管理到本地转换] WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0x50 字节 WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedAction action, object item, int index, int oldIndex) + 0x34 bytes WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.MoveItem(int oldIndex, int newIndex) + 0x6f 字节 WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection.Move(int oldIndex, int newIndex) + 0xe 字节 .Models.FCurve.MoveKey(int keyIndex = 1, double keyTime = 489.0) 第 199 行 + 0x19 字节 C# .Models.FCurve.KeyTimeChanged(Models.FCurveKey timeChangeKey = {Models.FCurveKey}) 第 186 行 + 0x2d 字节 C# .Models.FCurve.AddKeyToArray.AnonymousMethod(object sender = {Models.FCurveKey}, System.EventArgs args = {System.EventArgs}) 第 163 行 + 0x11 字节 C# [本机到托管转换] [管理到本地转换] .Models.FCurveKey.OnTimeChanged() 第 45 行 + 0x14 字节 C# .Models.FCurveKey..ctor.AnonymousMethod(object sender = {FCurveEditorTestApp.Impl.FCurveKeyImpl}, System.EventArgs args = {System.EventArgs}) 第 18 行 + 0x8 字节 C# [本机到托管转换] [管理到本地转换] FCurveEditorTestApp.exe!FCurveEditorTestApp.Impl.FCurveKeyImpl.OnTimeChanged() 第 43 行 + 0x14 字节 C# FCurveEditorTestApp.exe!FCurveEditorTestApp.Impl.FCurveKeyImpl.Time.set(double value = 489.0) Line 34 + 0x8 bytes C# .Models.FCurveKey.Time.set(double value = 489.0) 第 36 行 + 0x1b 字节 C# .ViewModels.CurveKeyViewModel.X.set(double value = 489.0) 第 32 行 + 0x2b 字节 C# .ViewModels.CurveAreaViewModel.MoveSelectedItem.AnonymousMethod(ViewModels.CurveKeyViewModel key = {ViewModels.CurveKeyViewModel}) 第 127 行 + 0x2d 字节 C# Collections.CollectionHelper.ForEach(System.Collections.Generic.IEnumerable source = {System.Linq.Enumerable.OfTypeIterator}, System.Action action = {Method = {Void b__8(ViewModels.CurveKeyViewModel)}}) 第 31 行 + 0xe 字节 C# .ViewModels.CurveAreaViewModel.MoveSelectedItem(double deltaX = 82.0, double deltaY = -9.0) 第 126 行 + 0x63 字节 C# Views.CurveAreaView._AreaCanvas_MouseMove(object sender = {System.Windows.Controls.Canvas}, System.Windows.Input.MouseEventArgs e = {System.Windows.Input.MouseEventArgs}) 第 195 行 + 0x2d 字节 C#

问题是:为什么会发生这种情况,我应该怎么做才能让它在断言时中断?

我想过使用异常,也许是为了调试,但它确实是我需要的断言。我也在考虑我所有其他的断言,而不需要总是将它们转换为异常进行调试......

【问题讨论】:

    标签: c# wpf assert


    【解决方案1】:

    您可以编写自己的TraceListener,在整个 AppDomain 范围内(如果您的应用程序只有一个 AppDomain,则在整个应用程序范围内)执行此操作。

    首先创建一个包含ExceptionTraceListener类的类库项目MyTraceListeners.dll:

    public class ExceptionTraceListener : TraceListener
    {
      public override void Write(string message)
      {
        // Do nothing
      }
      public override void Fail(string message)
      {
        Debugger.Break();  // or if you prefer, throw new Exception(...)
      }
      public override void Fail(string message, string detailMessage)
      {
        Debugger.Break();  // or if you prefer, throw new Exception(...)
      }
    }
    

    现在您可以像往常一样在应用程序的.config 文件中注册这个TraceListener:

    <configuration>
      ...
      <system.diagnostics>
        ...
        <trace>
          <listeners>
            <clear />
            <add name="myListener" type="ExceptionTraceListener, MyTraceListeners" />
          </listeners>
        </trace>
      </system.diagnostics>
    </configuration>
    

    当您使用这些 .config 文件条目运行您的应用程序时,调试器将在每次失败的断言时立即中断。

    还要注意此配置文件中的&lt;clear /&gt;,以清除Machine.config 中列出的任何默认TraceListeners。这很重要,因为默认的TraceListeners 会在你之前接到电话,并且仍然会弹出MessageBox。

    【讨论】:

      【解决方案2】:

      我以前见过这样的事情,当时可行的解决方法是添加一个 if 语句,其条件与断言相同,但被否定,并结合调试器中设置的断点在 then 块中的语句上如果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多