3

Canvas上でデータを移動するWPFアプリケーションがあります。問題は、フリークのようにマウスでデータを移動しようとしたときに始まりました。

アクションのシーケンスは次のとおりです。

  • キャンバス上のMouseMoveがトリガーされます
  • MouseMoveで、いくつかのデータを変更します
  • Trace.Assertが失敗します。デバッガーは壊れませんし、メッセージボックスも壊れません
  • 別のMouseMoveがトリガーされます
  • データが再び変更されます
  • コレクションの再入可能性チェックが原因で例外がスローされます。デバッガーはそこで壊れます。[アサート]メッセージボックスは表示されませんでした。

ここでの大きな問題は、アサーションに戻ることができるということですが、それはアサーションが失敗したときのデータではなく、最後に変更されたデータです...したがって、基本的にそれを正しくデバッグすることはできません。

これが最初の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)34行目+ 0x8バイト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})Line 195 + 0x2d bytes C#
  PresentationCore.dll!System.Windows.Input.MouseEventArgs.InvokeEventHandler(System.Delegate genericHandler、object genericTarget)+0x34バイト
  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(object source = {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 trusted)+0x35バイト
  PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea()+0x311バイト
  PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input)+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 mode、int timestamp、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 Handled = 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 Handled = 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 Handled = false)+0xbeバイト
  WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)+0x7aバイト
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback = {Method = {System.Object DispatcherCallbackOperation(System.Object)}}、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 callback、object args、bool isSingleParameter、System.Delegate catchHandler = null)+0x4aバイト
  WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegateコールバック、オブジェクト引数、bool isSingleParameter、System.Delegate catchHandler)+0x44バイト
  WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority、System.TimeSpan timeout、System.Delegate method、object args、bool isSingleParameter)+0x91バイト
  WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority priority、System.Delegate method、object 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バイト
  System.dll!System.Diagnostics.Trace.Assert(bool condition)+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}
  .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アクション、オブジェクトアイテム、intインデックス、int oldIndex)+0x34バイト
  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(オブジェクト送信者、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アクション、オブジェクトアイテム、intインデックス、int oldIndex)+0x34バイト
  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)34行目+ 0x8バイト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#

問題は、なぜこれが発生する可能性があるのか​​、そしてアサート時にそれを中断させるために何をすべきかということです。

おそらくデバッグのために例外を使用することを考えましたが、それは本当に私が必要としている主張です。デバッグのために常に例外に変換する必要なしに、他のすべてのアサートについても考えています...

4

2 に答える 2

5

独自のを作成することで、AppDomain全体(アプリケーションにAppDomainが1つしかない場合はアプリケーション全体)でこれを行うことができますTraceListener

まず、クラスMyTraceListeners.dllを含むクラスライブラリプロジェクトを作成しますExceptionTraceListener

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

これで、通常の方法でこれTraceListenerをアプリケーションのファイルに登録できます。.config

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

これらの.configファイルエントリを配置してアプリを実行すると、アサーションが失敗するたびにデバッガーがすぐに中断します。

にリストされている<clear />デフォルトをクリアするには、この構成ファイルのにあることにも注意してください。デフォルトのはあなたの前に呼び出しを受信し、それでもポップアップするので、これは重要です。TraceListenersMachine.configTraceListenerMessageBox

于 2009-11-19T00:28:34.627 に答える
0

私は以前にこのようなものを見たことがありますが、その時点で機能した回避策は、アサートと同じ条件でifステートメントを追加することでしたが、ifのthenブロックのステートメントにデバッガーで設定されたブレークポイントと組み合わせて否定されました。

于 2009-11-18T16:36:32.770 に答える