线程无法访问该对象

Nic*_*kon 3 c# wpf multithreading invalidoperationexception

我宣布了一个字段:

WriteableBitmap colorBitmap;
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个简单的线程来执行某些操作

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

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

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

问题是我无法改变myImage的来源.我有一个错误,如:

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

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

Application.Current.Dispatcher.Invoke((Action)delegate
{
    myImage.Source = colorBitmap;
});
Run Code Online (Sandbox Code Playgroud)

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

GET*_*Tah 9

您的代码有两个问题:

  1. 您无法访问与WriteableBitmap创建它的人不同的另一个线程.如果你想做到这一点,你需要通过调用冻结您的位图WriteableBitmap.Freeze()第一

  2. 您不能myImage.Source在不是调度程序线程的线程中访问.

这应该解决这两个问题:

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

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

另外,如果您不希望阻止线程更新myImage.Source使用BeginInvoke而不是Invoke