2017-12-21 3 views
-1

Ich habe das Muster unter Async OOP definiert, um ein Ansichtsmodell zu erstellen, das Daten aus 2 Quellen liest. Wenn jedoch I einrichten CollectionViewSource und Filter für die Sammlung Versuchen erhalten ich eine Ausnahme Additional information: Must create DependencySource on same Thread as the DependencyObject. oder, wenn die Datenfilterung erhalten I die folgende Ausnahme The calling thread cannot access this object because a different thread owns it.Async Viewmodel Konstruktor Initialisierung von Daten

Die Eigenschaften definiert werden als

folgt
public NotifyTaskCompletion InitializationNotifier{ get; set; } 
    public Task Initialization => InitializationNotifier.Task; 

Der Ansichtsmodell Konstruktor definiert die InitializationNotifier wie folgt:

InitializationNotifier = new NotifyTaskCompletion(InitializeAsync()); 

die Aufgabe wird wie folgt definiert:

private async Task InitializeAsync() 
    { 
     var aDataSource = await Task.Run(() => ADataSource.Get(1, 2)); 
     var bDataSource = await Task.Run(() => new BDataSource(1, 2); 
     PrepareData(aDataSource, bDataSource); // creates List<T> for different categories 
     SetupCollections(); // Creates Observable collections from List<T> 
     SetupCVSAndFilters(); // Creates CollectionViewSource for different categories 
    } 

    private void SetupCollections() 
    { 
     AStars = new ObservableCollection<IAEntity>(m_aStars); 
     BStars = new ObservableCollection<IAEntity>(m_bStars); 
    } 
    // Setup Collectionview source and Filters 
    // Get an exception: 
    // Additional information: Must create DependencySource on same Thread as the DependencyObject. 
    private void SetupCVSAndFilters() 
    { 
     AStarsCVS = new CollectionViewSource { Source = AStars }; 
     BStarsCVS = new CollectionViewSource { Source = BStars }; 
     AStarsCVS.View.Filter = FilterCompareData; 
     BStarsCVS.View.Filter = FilterCompareData; 
    } 

Die Ansicht/Ansichtsmodell funktioniert gut ohne Async/Task zu verwenden, aber die Abholungen von den Datenquellen sind zeitaufwendig (PInvoke s) und ich mehrere Registerkarten, die unterschiedlichen Daten gelesen und ich habe geschätzt Zeiger mir zu helfen, zu verstehen wo ich falsch bin mit der Verwendung von Task/Async

+2

Wenn Sie wirklich verstehen wollen, was hier vor sich geht, können Sie Concurrency Visualizer installieren (https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.ConcurrencyVisualizer2017). Sie können es mit einer einfachen API (https://www.nuget.org/packages/ConcurrencyVisualizer/) verwenden, mit der Sie Abschnitte in Ihrem Code markieren und beobachten können, auf welchen Threads sie ausgeführt werden (https://msdn.microsoft .com/de-de/en-de/library/hh755853.aspx). Es ist wirklich abgefahren. –

Antwort

1

Jedes Mal, wenn Sie Task.Run() aufrufen, wird ein neuer Thread erstellt. Die Ausnahmen, die du bekommst, haben damit zu tun, dass deine Threads versuchen, auf andere Art und Weise zuzugreifen, auf die sie nicht zugreifen sollen. Ich glaube nicht, dass ich durch den bereitgestellten Code sehen kann, wo es schief geht, aber ich kann Ihnen sagen, dass in WPF Threads unter Verwendung von Dispatcher.BeginInvoke() auf die Objekte anderer Threads zugreifen können.

Es sieht auch so aus, als ob Sie nicht die Vorteile der asynchronen Programmierung erhalten, die Sie suchen. Wenn Sie nacheinander zwei await Anweisungen haben, bedeutet dies, dass die erste Aufgabe abgeschlossen wird, bevor die zweite überhaupt beginnt. Ich denke du willst Task.WaitAll().

+1

Warum abgelehnt? Das ist eine richtige Antwort - es reicht nicht aus, um zu sagen, was passiert, da wir nicht wissen, ob der View-Modellkonstruktor von einem UI-Thread aufgerufen wurde. –

+0

@swiszcz Ich habe es nicht abgelehnt, ich stimme zu, dass ich mehr Code zur Verfügung gestellt hätte. Das view/viewmodel ist ein Tab-Inhalt und der viewmodel-Konstruktor wird tatsächlich von einem UI-Thread aufgerufen. – rahul

Verwandte Themen