从Different Thread读取DependencyProperty

时间:2013-02-05 02:31:30

标签: c# dependency-properties finalizer

我遇到了析构函数问题。以下是重新解决问题的代码:

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

当析构函数运行时,我在行get {SetValue...上得到一个InvalidOperationException。是否有推荐的方法从析构函数或其他一般线程读取dependecy属性?

2 个答案:

答案 0 :(得分:4)

~ClassName()函数不是析构函数,它是终结函数。它提供的工作与C ++析构函数完全不同。一旦进入对象生命周期的终结器阶段,就无法可靠地调用该类包含的其他对象,因为在调用终结器之前它们可能已经被销毁。你应该在终结器中做的唯一事情是释放非托管资源或在正确实现的配置模式中调用Dispose(false)函数。

如果您需要“析构函数”,则需要实现IDisposable模式correctly以使代码以正确的方式运行。

另请参阅this question and answer以获取有关编写良好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.
    }
}

答案 1 :(得分:0)

我建议使用IDisposable接口,并在Dispose方法中操作DependencyObject。