2016-03-21 6 views
2

Ich habe eine Multithread-App, und ich muss ein Objekt aus einem anderen Thread zur Baumansicht hinzufügen. Aber ich bekomme immer eine AusnahmeSo fügen Sie ein Objekt in der Baumansicht eines anderen Threads hinzu

Aktion, die für dieses Steuerelement ausgeführt wird, wird aus dem falschen Thread aufgerufen. Marschall zum richtigen Thread mit Control.Invoke oder Control.BeginInvoke, um diese Aktion durchzuführen.

Hier ist mein Code

ThreadPool.QueueUserWorkItem(new WaitCallback(GetFiles), entryPoint); 

private void GetFiles(object entryPoint) 
{ 
     var localData = entryPoint as EntryPoint; 
     this.GetFiles(localData.DirectoryInfo, localData.TreeNode); 
     localData.ManualEvent.Set(); 
} 

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    for (int i = 0; i < allFiles.GetLength(0); i++) 
    { 
     tree.Nodes.Add(allFiles[i].Name); 
    } 
} 
+1

Dies ist eine Standardnachricht. Sie können Elemente, die vom UI-Thread aus einem Nicht-UI-Thread erstellt wurden, nicht ändern. Verwenden Sie BeginInvoke() mit einem anonymen Delegaten oder einem gewöhnlichen Delegaten auf dem Hauptformular von Ihrem Thread. Ich denke, Lambda und Linq bieten sogar bessere Methoden. – icbytes

+0

Ich mache mit Hilfe von Delegat, aber immer noch eine Ausnahme öffentlichen Delegat void MyDelagate (TreeNode Baum, String-Wert); public MyDelagate TreeViewDelegate; TreeViewDelegate = Delegat (TreeNode-Struktur, Zeichenfolge s) { tree.Nodes.Add (s); }; TreeViewDelegate.Invoke (Baum, allFiles [i] .Name); – Ilia

+0

IMHO müssen Sie 'ThreadPool' überhaupt nicht verwenden. Rufen Sie einfach die Methode im UI-Thread auf. Ihre Methode macht keine nennenswerte Arbeit. –

Antwort

2

Da die Fehlerzustände, müssen Sie UI bezogenen Aktionen auf dem UI-Thread auszuführen. Um dies zu tun, können Sie BeginInvoke von der Steuerung selbst verwenden.

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    if (TreeViewControl.InvokeRequired) 
    { 
     TreeViewControl.BeginInvoke((MethodInvoker)delegate 
     { 
      for (int i = 0; i < allFiles.GetLength(0); i++) 
      { 
       tree.Nodes.Add(allFiles[i].Name); 
      } 
     }); 
    } 
} 

Sie finden weitere Informationen here.

+0

Wie wird der Dispatcher in der WinForms App verwendet? – Ilia

+0

Ist das WinForms? Ihr Tag gibt WPF an. –

+0

Entschuldigung, meine Schuld – Ilia

4

Ich glaube, Sie müssen dies tun:

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => GetFiles(directory, tree))); 
+0

Willkommen bei Stack Overflow! Während dieser Code die Frage beantworten könnte, wäre es besser, etwas _context_ einzufügen, _how_ es funktioniert zu erklären und _when_, um es zu benutzen. Nur-Code-Antworten sind auf lange Sicht nicht nützlich. –

+0

In Windows Forms gibt es keinen 'Dispatcher'! – Enigmativity

+0

@Enigmatistik die Frage wurde markiert [tag: wpf] wenn diese Antwort gepostet wurde. –