线程无法访问该对象

时间:2012-06-27 13:00:51

标签: c# wpf multithreading invalidoperationexception

我宣布了一个字段:

WriteableBitmap colorBitmap;

然后我创建了一个简单的线程,它做了一些事情:

private void doSomething()
{
    // ... bla bla bla
    colorBitmap = new WriteableBitmap(/* parameters */);
    myImage.Source = colorBitmap; // error here:S
}

在Windows_Loaded事件中,我声明并启动了一个新线程:

private void window_Loaded(object sender, RoutedEventArgs e)
{
    Thread th = new Thread(new ThreadStart(doSomething));
    th.Start();
}

问题在于我无法更改myImage的来源。我有一个错误:

  

InvalidOperationException未处理   调用线程无法访问此对象,因为另一个线程拥有它。

我尝试使用Dispatcher.Invoke,但它没有帮助......

Application.Current.Dispatcher.Invoke((Action)delegate
{
    myImage.Source = colorBitmap;
});

我正在寻找一些答案,但从来没有像我一样找到这个案子。 any1帮助我理解如何解决这样的问题(我最近遇到了同样的问题,但我无法调用该方法,因为其他线程拥有它)。

1 个答案:

答案 0 :(得分:9)

您的代码存在两个问题:

  1. 您无法从另一个与创建它的线程不同的线程访问WriteableBitmap。如果你想这样做,你需要先调用WriteableBitmap.Freeze()来冻结你的位图

  2. 您无法在不是调度员线程的线程中访问myImage.Source

  3. 这应解决这两个问题:

    private void doSomething()
    {
        // ... bla bla bla
        colorBitmap = new WriteableBitmap(/* parameters */);
        colorBitmap.Freeze();
        Application.Current.Dispatcher.Invoke((Action)delegate
        {
            myImage.Source = colorBitmap;
        });
    }
    

    修改 请注意,此方法允许您在线程中的任何位置创建和更新位图。一旦位图被冻结,就不能再修改它,在这种情况下你应该删除它并创建一个新位置。

    在旁注中,如果您不希望阻止线程更新myImage.Source,请使用BeginInvoke代替Invoke