允许从后台线程访问DispatcherObject

时间:2014-03-21 14:53:55

标签: c# wpf multithreading

我知道我在阅读一些教程时理解DispatcherObject是如何工作的,但在我使用它时却感到困惑。 这是我的计划:

namespace DispatcherObjectDemo
{
    public partial class MainWindow : Window
    {
        Foo foo;

        public MainWindow()
        {
            InitializeComponent();
            this.foo = new Foo();
        }

        private void Parallel(object sender, RoutedEventArgs e)
        {
            Task task = new Task(() => ChangeFoo());
            task.Start();
        }

        private void ChangeFoo()
        {
            // Protect from accessing to foo in background thread
            if (this.foo.CheckAccess())
            {
                this.foo = new Foo();
            }
        }
    }

    public class Foo : DispatcherObject
    {
        public string Name
        { 
            get; 
            set; 
        }
    }
}

所以我的想法是保护对foo对象的访问。 CheckAccess()作为描述符工作,并阻止分配对foo对象的新引用。 我的理解是,如果我不保护我的代码,我将有InvalidOperationException。

但是当我删除它以试一试时,它没有任何异常。

private void ChangeFoo()
{
    this.foo = new Foo();
}

有任何解释吗?

2 个答案:

答案 0 :(得分:0)

调用

private void ChangeFoo()
{
    this.foo = new Foo();
}
任务池线程上的

不应抛出任何异常。您只是创建一个新对象并将其分配给一个字段。

您指的是InvalidOperationException,如果在不是调度程序线程的线程上调用该方法,则对DispatcherObject.VerifyAccess的调用将抛出InvalidOperationException是正确的。但是,调用new Foo()不会调用VerifyAccess,因此您不会例外。

如果你想要"无效"要抛出异常的代码,您应该调用VerifyAccess而不是CheckAccess

答案 1 :(得分:0)

谢谢, 但是线程亲和力呢:

  

...这称为线程亲和力,这意味着您只能使用WPF   对象在创建它的线程上。在其他地方使用它   线程将导致抛出运行时异常......

我的承诺是,创建un UI线程的WPF对象只能用于非UI线程,从后台线程调用它们会抛出异常。