线程问题"因为不同的线程拥有它&QUOT调用线程不能访问该对象;.任何解决方案? [英] Threading issue "The calling thread cannot access this object because a different thread owns it". Any solutions?

查看:125
本文介绍了线程问题"因为不同的线程拥有它&QUOT调用线程不能访问该对象;.任何解决方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含文件名列表视图。我有一个包含可能的行动来重命名这些文件列表视图另一个。最后我有一个显示结果的预览的标签。当在每个列表中选择一个对象我想显示的预览。您只能选择一个文件,但一个或多个动作。我使用WPF / XAML中我的UI。我选择了一个线程中执行我的预览

I have a listview that contains file names. I have another listview that contains possible actions to rename these files. Finally I have a label that displays a preview of the result. When an object is selected in each of the lists I want to display the preview. You can select only one file but one or more actions. I use WPF/Xaml for my UI. I chose to perform my preview with a thread.

下面是我的代码的一部分:

Here is a part of my code :

    private Thread _thread;

    public MainWindow()
    {
        InitializeComponent();
        _thread = new Thread(DoWork);
    }

    public void DoWork()
    {
        while (true)
        {
            FileData fileData = listViewFiles.SelectedItem as FileData; // ERROR HERE
            if (fileData != null)
            {
                string name = fileData.FileName;
                foreach (var action in _actionCollection)
                {
                    name = action.Rename(name);
                }
                previewLabel.Content = name;
            }
            Thread.Sleep(1000);
        }
    }

    private void listViewFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        _thread.Start();
    }



在运行时出现错误调用线程不能访问此对象,因为不同的线程拥有它。上的FileData FILEDATA = listViewFiles.SelectedItem为的FileData;线。你知不知道我该怎么办?

At run time I get the error "The calling thread cannot access this object because a different thread owns it." on the FileData fileData = listViewFiles.SelectedItem as FileData; line. Do you know what should I do ?

推荐答案

您不能修改或nonUI线程访问UI。所以,如果你仍然想使用你需要做不同的线程第一件事是添加某种模式(有关绑定和模型的尝试搜索WPF MVVM更多信息),然后将其绑定您 listViewFiles。的SelectedItem 这种模式的某些属性,这将让你在线程访问的SelectedValue。其次,你需要单独改变用户界面方法或使用拉姆达所有的逻辑,这样最终就可以是这样的:

You can't modify or access UI from nonUI thread. So if you still want to use different thread first thing you need to do is to add some kind of model (for more info about binding and model try search for "wpf mvvm"), then bind you listViewFiles.SelectedItem to some property of this model this will allow you to access SelectedValue across threads. Second you need to separate all logic that changes UI to method or use lambda so in the end it can look like this:

public void DoWork() 
{ 
    while (true) 
    { 
        FileData fileData = Model.SelectedValue;
        if (fileData != null) 
        { 
            string name = fileData.FileName; 
            foreach (var action in _actionCollection) 
            { 
                name = action.Rename(name); 
            } 
            this.Dispatcher.Invoke((Action)()=>  //use Window.Dispatcher
            {
              label3.Content = fileData.FileName; 
              label4.Content = name;
            }); 
        } 
        Thread.Sleep(1000); 
    } 
} 



UPD。关于与UI同步一些额外的话:在每一个WPF UI对象从的 DispatcherObject的类。因此,这种类型的对象,所有的访问只能在此创建对象,如果你想从你需要使用 DO.Dispatcher.Invoke另一个线程访问DispatcherObject的(DO)线程进行(代表)的方法,这将排队等待你的代码做线程。所以在最后运行在UI线程代码,你需要使用Dipatcher任何UI元素在此情况下,我们使用Window的调度员(假设窗口代码,后面的代码)。

UPD. Some additional words about synchronizing with UI: in WPF every UI object inherits from DispatcherObject class. Thus all access to object of this type can be made only from thread in which this object was created, if you want to access DispatcherObject(DO) from another thread you need to use DO.Dispatcher.Invoke(Delegate) method, this will queue your code to DO thread. So in conclusion to run code in UI thread you need to use Dipatcher of any UI element in this case we use Dispatcher of Window (assume that code in window code behind).

这篇关于线程问题"因为不同的线程拥有它&QUOT调用线程不能访问该对象;.任何解决方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆