我为我的代码添加了一个事件处理程序,它破坏了对SystemHTA类中CollectionViewSources的所有访问,说“调用线程无法访问此对象,因为另一个线程拥有它”。我的班级在“this.systemHTA = new SystemHTA();”时正在工作被放置在DeviceManager_StateChanged()函数之外。
public partial class MainWindow : Window
{
private DeviceManager DeviceManager = DeviceManager.Instance;
public SystemHTA systemHTA;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DeviceManager.StateChanged += new EventHandler<DeviceManagerStateChangedEventArgs>(DeviceManager_StateChanged);
DeviceManager.Initialize();
}
void DeviceManager_StateChanged(object sender, DeviceManagerStateChangedEventArgs e)
{
if (e.State == DeviceManagerState.Operational)
{
this.systemHTA = new SystemHTA();
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.systemHTA.GetViewSourceTest();
}
}
public class SystemHTA
{
private CollectionViewSource _deviceTestSource;
public SystemHTA()
{
_deviceTestSource = new CollectionViewSource();
_deviceTestSource.Source = CreateLoadData<HWController>.ControllerCollection;
}
public void GetViewSourceTest()
{
ListCollectionView view = (ListCollectionView)_deviceTestSource.View; //This creates an error saying a thread already owns _deviceTestSource
}
}
答案 0 :(得分:0)
您在这里寻找的是Dispatcher.BeginInvoke。看看这里有一个完整的解释:
以下是一些更具体的帮助,可以帮助您前进:
祝你好运。答案 1 :(得分:0)
以下是一些使用Invoke解决问题的示例代码:cross thread operation not valid。您需要从创建线程访问信息。
答案 2 :(得分:0)
好的,CollectionViewSource派生类,BindableList,ObservableCollection等这些类只能在主调度程序线程中创建。
但是你必须尝试以下排序, 仅在WPF派生类中创建collectionviewsource,使用List&lt;&gt;用于在不同线程中加载对象的类,一旦完成,您可以从列表转移到collectionviewsource,如下所示,我建议使用BindingList,因为您可以添加多个项目来禁用刷新以消除闪烁。
在WPF类中隐式创建集合对象,如下所示
public class MyWindow : UserControl{
BindingList<MyObject> ObjectList = new BindingList<MyObject>;
public MyWindow(){
ObjectList.AllowAdd = true;
ObjectList.AllowDelete = true;
ObjectList.AllowEdit = true;
}
public void LoadObjects(){
ThreadPool.QueryUserItem( (s)=>{
// load your objects in list first in different thread
List<MyObject> list = MyLongMethodToLoadObjects();
Dispatcher.BeginInvoke( (Action)delegate(){
list.RaiseEvents = false;
foreach(MyObject obj in list){
ObjectList.Add(obj);
}
list.RaiseEvents = true;
list.ResetBindings();
});
});
}
}
我不知道这段代码格式不正确,但你可以尝试在visual studio中看到它以获得正确的想法。
答案 3 :(得分:0)
简单而稳定的解决方案是使用 BackgroundWorker 。 阅读这篇文章BackgroundWorker