代码之家  ›  专栏  ›  技术社区  ›  Bob Wintemberg

已完成的线程中的对象上的InvalidOperationException

  •  2
  • Bob Wintemberg  · 技术社区  · 16 年前

    在一个WPF应用程序中,我有一个backgroundworker线程创建了一个对象。让我们称之为对象foo。

    后台工作人员代码:

    SomeClass foo = new SomeClass();
    // Do some operation on foo
    
    // Set some dependency property on the main class to foo
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        (SendOrPostCallback)delegate { SetValue(FooProperty, foo); },
        foo);
    

    现在,当主类尝试使用getter访问fooproperty时,我得到一个InvalidOperationException:调用线程无法访问此对象,因为另一个线程拥有它。

    如果创建对象的线程完成,为什么它仍然拥有该对象?这附近有什么路吗?

    3 回复  |  直到 16 年前
        1
  •  2
  •   helios456    16 年前

    在给定线程中创建的对象属于该线程。这就是为什么你会得到一个无效的操作异常。如果要在后台线程中设置属性,建议委托返回所需的值并从主线程调用set value。(创建对象的线程)。

        2
  •  1
  •   JaredPar    16 年前

    WPF中的绝大多数对象都具有线程关联性。一旦在一个特定的线程上创建了这个对象,那么只有在从该线程使用时,WPF对象才会运行。这一限制(与WinForms不同)实际上是对您在该对象上所做的每一个操作强制执行的。

    您需要更改您的代码,以便在此场景的实际UI线程上创建foo。

        3
  •  1
  •   GraemeF    16 年前

    假设 SomeClass 来源于 DispatcherObject ,创建它的线程运行负责处理 foo 对象。因此,如果线程结束,那么对象就不能再处理消息,这不是一个好主意。

    在大多数情况下,您应该使用同一个UI线程来创建您的所有UI对象(或派生自 Dispatcher对象 并确保它在应用程序期间运行。然后使用 Dispatcher 从工作线程向其发送消息。