1

デストラクタの問題が発生しています。問題を再現するコードは次のとおりです。

class DPDemo : DependencyObject
{
    public DPDemo()
    {

    }

    ~DPDemo()
    {
        Console.WriteLine(this.Test);   // Cross-thread access
    }

    public int Test
    {
        get { return (int)GetValue(TestProperty); }
        set { SetValue(TestProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Test.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TestProperty =
        DependencyProperty.Register("Test", typeof(int), typeof(DPDemo), new PropertyMetadata(0));
}

デストラクタを実行すると、行でInvalidOperationExceptionが発生しますget {SetValue...。デストラクタまたは一般的な別のスレッドから依存関係のプロパティを読み取るための推奨される方法はありますか?

4

2 に答える 2

4

~ClassName()関数はデストラクタではなく、ファイナライザです。C++ デストラクタとは非常に異なる役割を果たします。オブジェクトのライフサイクルのファイナライザー段階に入ると、ファイナライザーが呼び出される前に既に破棄されている可能性があるため、クラスに含まれる他のオブジェクトを確実に呼び出すことはできません。ファイナライザーで実行する必要があるのは、アンマネージ リソースを解放するか、正しく実装された破棄パターンで Dispose(false) 関数を呼び出すことだけです。

「デストラクタ」が必要な場合は、IDisposable パターンを正しく実装して、コードが適切に動作するようにする必要があります。

優れた IDisposable パターンを作成するためのヒントについては、この質問と回答も参照してください。また、エラーが発生する理由を説明するのにも役立ちます (彼がファイナライザーについて話し始めた部分を参照してください)。


あなたのコメントに答えるには:いいえ、そうではありません。C# には、オブジェクトの有効期限が切れたときに自動的に関数を確実に呼び出す方法がありません(IDisposableクラス +usingステートメントはそれを置き換えます)。オブジェクトが実装IDisposableする場合、オブジェクトを破棄するのは呼び出し元の責任です。

WPF アプリのメソッドで、クラスの機能OnCloseを呼び出す必要があります。Saveクラスがまったく必要ありませんIDisposable

//Inside the codebehind of your WPF form
public partial class MyWindow: Window
{
    //(Snip)

    protected override void OnClosed(EventArgs e) //You may need to use OnClosing insetad of OnClose, check the documentation to see which is more appropriate for you.
    {
        _DPDemoInstance.Save(); //Put the code that was in your ~DPDemo() function in this save function.
                                //You could also make the class disposeable and call "Dispose()" instead.
    }
}
于 2013-02-05T08:44:45.480 に答える
0

IDisposable インターフェイスを使用し、Dispose メソッドで DependencyObject を操作することをお勧めします。

于 2013-02-05T08:10:04.780 に答える