Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”的问题相关的知识,希望对你有一定的参考价值。

<Grid>
<UniformGrid Rows="2" Margin="0,0,0,40">
<Label Name="lab1" Content="1"></Label>
<Label Name="lab2" Content="2"></Label>
</UniformGrid>
<Button Content="Play" Width="40" Height="30" Name="play" VerticalAlignment="Bottom" Click="play_Click"></Button>
</Grid>

代码中写了很简单的一个线程
private void play_Click(object sender, RoutedEventArgs e)//按钮响应事件

Thread th = new Thread(refresh);
th.IsBackground = true;
th.Start();

void refresh()

while(true)

ActualDraw(8);


public delegate void DrawHandler(int n);
void Draw(int n)

App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new DrawHandler(ActualDraw), n);

void ActualDraw(int n)

lab1.Content = n.ToString();

哪里有问题?
对不起
是我写错了

应该是代码中
while循环中

ActualDraw(8);改为Draw(8);即可,是我写错了

参考技术A

refresh方法改成这样就对了:

 void refresh()
        
            int i = 0;
            while (true)
            
                i++;
                Thread.Sleep(1000);
                Draw(i);
            
        

参考技术B ActualDraw(8);

换成委托试试

Draw(8);

本回答被提问者采纳

Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”

我的xaml中
<Grid>
<UniformGrid Rows="2" Margin="0,0,0,40">
<Canvas Name="Image1" Margin="5" Background="#FFFFC0C0"></Canvas>
</UniformGrid>
<Button Content="Play" Width="40" Height="30" Name="play" VerticalAlignment="Bottom" Click="play_Click"></Button>
</Grid>
代码中写了很简单的一个线程

private void play_Click(object sender, RoutedEventArgs e)//按钮响应事件

Thread th = new Thread(refresh);
th.IsBackground = true;
th.Start();

void refresh()

while (true)

BitmapImage imagelist = new BitmapImage(new Uri("D:\\VS2010\\Project\\PreView\\PreView\\bin\\Debug\\1.jpg"));
Draw(imagelist);


public delegate void DrawHandler(BitmapImage bitmap);
void Draw(BitmapImage bitmap)

App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new DrawHandler(ActualDraw), bitmap);

void ActualDraw(BitmapImage bitmap)

Image1.Background = new ImageBrush(bitmap);
//如果将这里换成Image1.Background = new BitmapImage(new Uri("D:\\VS2010\\Project\\PreView\\PreView\\bin\\Debug\\1.jpg"));就没有问题了?为什么?


哪里写的有问题?

这是因为bitmap控件是在你新开的线程里面创建的.而你委托后在主线程里面去调用他,就出错了.

如果是在主线程里面New 一个图片的话是可以的.
BitmapImage imagelist = new BitmapImage(new Uri(@"D:\\VS2010\\Project\\PreView\\PreView\\bin\\Debug\\1.jpg"));
void ActualDraw(BitmapImage bitmap)

Image1.Background = new ImageBrush(imagelist);
追问

我已经找到原因了
是BitmapImage资源无法释放的问题
在while (true)

imagelist.Freeze();//new后面加上这句就OK
Draw(imagelist);

追答

imagelist.Freeze();
此方法不是释放资源,而是冻结依赖项属性.
这个方法将imagelist的内部的Dispatcher属性设置为空,所以任何线程调他都不会出错.

追问

哦 这样 谢谢

参考技术A bitmap资源之前被调用过,没有释放,所以再调用时无法访问。 参考技术B 应该是你在在线程创建了控件,却在一个新的线程中调用它了。
这是多线程中常见问题

以上是关于Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”的问题的主要内容,如果未能解决你的问题,请参考以下文章

wpf中怎么查找控件啊

wpf开发中 xaml 添加名称空间

wpf中怎么为treeview动态添加子菜单

如何解决wpf中绘图的卡顿

wpf 带参数的用户控件,如何在xaml中引入

wpf 窗体中如何取得xaml的路径