使用WPF进行多线程处理

使用WPF进行多线程处理,wpf,multithreading,task,Wpf,Multithreading,Task,不幸的是,我得到了以下错误 + $exception {"Von diesem CollectionView-Typ werden keine Änderungen der \"SourceCollection\" unterstützt, wenn diese nicht von einem Dispatcher-Thread aus erfolgen."} System.NotSupportedException 我的代码是用来显示错误的测试代码 using System;

不幸的是,我得到了以下错误

+       $exception  {"Von diesem CollectionView-Typ werden keine Änderungen der \"SourceCollection\" unterstützt, wenn diese nicht von einem Dispatcher-Thread aus erfolgen."}  System.NotSupportedException
我的代码是用来显示错误的测试代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp5_Task_und_darstellun_test
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Transfer tr = new Transfer();
        public MainWindow()
        {
            InitializeComponent();
            ObservableCollection<int> Data = new ObservableCollection<int>();



            new Task(() => { tr.GetData(Data); }).Start();

            while (true)
            {


                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    // Code für den UI Thread
                    listView1.ItemsSource = Data;
                    CollectionViewSource.GetDefaultView(listView1.ItemsSource).Refresh();
                }));
            }
        }
        private void listView1_SelectionChanged(object sender,
        SelectionChangedEventArgs e)
        {
        }
    }
    public class Transfer
    {
        public ObservableCollection<int> GetData(ObservableCollection<int> data)
        {
            while (true)
            {


                for (int i = 0; i < 2; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        int d = i + j;
                        data.Add(d);
                    }
                }return data;
            }
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
名称空间WpfApp5_任务和Darstellu测试
{
/// 
///Interaktionslogik für MainWindow.xaml
/// 
公共部分类主窗口:窗口
{
传输tr=新传输();
公共主窗口()
{
初始化组件();
ObservableCollection数据=新的ObservableCollection();
新任务(()=>{tr.GetData(Data);}).Start();
while(true)
{
Application.Current.Dispatcher.Invoke(新操作(()=>
{
//代码für den UI线程
listView1.ItemsSource=数据;
CollectionViewSource.GetDefaultView(listView1.ItemsSource.Refresh();
}));
}
}
私有无效列表视图1\u选择已更改(对象发送方,
选择ChangedEventArgs(e)
{
}
}
公共类转移
{
公共ObservableCollection GetData(ObservableCollection数据)
{
while(true)
{
对于(int i=0;i<2;i++)
{
对于(int j=0;j<3;j++)
{
int d=i+j;
数据.添加(d);
}
}返回数据;
}
}
}
}

我怎样才能解决它。我的真实代码应该有一个无结尾的for循环,结果(作为列表)应该写在listview中

您将dispatcher放在了错误的函数中:MainWindows已经在主线程上;但是Transfer.GetData()不是

将Transfer.GetData更改为

while (true)
{
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 3; j++)
            {
                int d = i + j;
                Application.Current.Dispatcher.Invoke(
                    new Action(() => { data.Add(d); }));
            }
        }
    return data;
}
while(true)
{
对于(int i=0;i<2;i++)
{
对于(int j=0;j<3;j++)
{
int d=i+j;
Application.Current.Dispatcher.Invoke(
新操作(()=>{data.Add(d);}));
}
}
返回数据;
}

同时修复你的白空间

首先,摆脱冷任务和构造函数中的无限循环。您使用任务就像使用线程一样。他们不是。不要创建冷任务,不要使用开始,不要在任务内部使用循环。或者在里面调用。任务就是任务。运行很短时间的东西,完成后,您更新UI,然后执行下一个UI。代码需要大量简化和重写。例如,如果使用
var result=wait Task.Run(someFunc)您可以在任务完成后直接更新UI,因为
wait
会将执行返回到UI线程。当视图线程尝试枚举集合(重新绘制集合)时,另一个线程是否正在修改它?尝试某种同步技术(像lock()这样的简单方法可能会起到作用,只是为了测试目的)。您是否按照中所述进行了尝试?谢谢您的帮助。只剩下一件事,我必须如何以及在何处集成listView1.ItemsSource=Data;CollectionViewSource.GetDefaultView(listView1.ItemsSource.Refresh();它会自动刷新用户界面,而你不会。可观察集合负责这一点:无论何时添加元素,它都会触发其onChange事件。listView附加到该事件,并在发生该事件时刷新自身。有关更多详细信息,请参阅