0

Unfortuanetly I get the following error

+       $exception  {"Von diesem CollectionView-Typ werden keine Änderungen der \"SourceCollection\" unterstützt, wenn diese nicht von einem Dispatcher-Thread aus erfolgen."}  System.NotSupportedException

My Code is a test Code in order to show the error

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;
            }
        }
    }

}

How can I solve it. My real Code should Have a non ending for Loop and the results (as a List) should be written in a listview

  • 1
    To start, get rid of the cold task, and the infinite loop in a constructor. – JSteward Apr 27 '17 at 16:07
  • 5
    You are using Tasks as if they were threads. They aren't. Don't create a cold task, don't use Start, don't use a loop inside the task. Or call Invoke inside it. A *task* is a *task*. Something that runs for a short time, finishes, you update your UI then execute the next one. The code needs a lot of simplification and rewriting. For example if you use `var result=await Task.Run(someFunc);` you can update the UI directly after the task finishes, since `await` returns execution to the UI thread. – Panagiotis Kanavos Apr 27 '17 at 16:08
  • Is the problem that whilst the view thread is trying to enumerate the collection (to redraw it), the other thread is modifying it? Try some sort of synchronisation technique (something simple like lock() might do, just for testing purposes). – Neil Apr 27 '17 at 16:10
  • Have you tried [BindingOperations.EnableCollectionSynchronization](http://msdn.microsoft.com/en-us/library/hh198861.aspx) as described at http://stackoverflow.com/questions/2091988/how-do-i-update-an-observablecollection-via-a-worker-thread ? – mechanic Apr 27 '17 at 16:16

1 Answers1

0

You've put the dispatcher in the wrong function: MainWindows is already on the main thread; But Transfer.GetData () isn't.

Change Transfer.GetData to

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;
}

also fix your whitepaces!

wotanii
  • 2,470
  • 20
  • 38
  • Thanks for your help. There is just one Thing left, how and where do I have to integrate listView1.ItemsSource = Data; CollectionViewSource.GetDefaultView(listView1.ItemsSource).Refresh(); that it will refresh the user Interface automatically –  Apr 28 '17 at 08:07
  • You don't. The observable collection takes care of that: Whenever you add an element, it triggers its onChange-Event. And the listView is attached to that event and will refresh itself when that happens. For more detail see https://msdn.microsoft.com/en-us/library/ms748365(v=vs.110).aspx – wotanii Apr 28 '17 at 08:27