3

我有一点问题。向TreeView添加节点会导致线程异常

我做了一个类来管理我的预制件(用于我的关卡编辑器的预定义对象)。 在开始加载预制时,它会为类别和每个预制创建TreeNodes,并将其添加到它由构造函数知道的TreeView中。

问题是,每次将节点添加到另一个节点时,都会导致“InvalidOperationException”,因为它不是正确的线程。我应该调用控件。 我试过了,它是同一个线程 - 它只在“LoadForm”事件中调用。

Here's我的PrefabManager级代码:

 public PrefabManager(TreeView tree) 
    { 
     _tree = tree; 
     _prefabs = new List<Prefab>(); 
    } 

    public void LoadPrefabs() 
    { 
     if (!Directory.Exists(_prefabPath)) 
      Directory.CreateDirectory(_prefabPath); 

     _tree.Nodes["RootNode"].Nodes.Clear(); 

     foreach (string file in Directory.GetFiles(_prefabPath, "*.pref", SearchOption.AllDirectories)) 
     { 
      Prefab prefab = Prefab.Load(file); 
      if (_prefabs.Count > 0) 
       if (_prefabs.Where(pfab => pfab.CreationName == prefab.CreationName).FirstOrDefault() != null) continue; 

      TreeNode categoryNode = GetCategoryOrCreate(prefab.Category); 
      TreeNode prefabNode = new TreeNode(prefab.CreationName) 
             { 
              ImageIndex = 2, 
              SelectedImageIndex = 2, 
              Tag = "Prefab" 
             }; 
      MessageBox.Show(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()); 
      categoryNode.Nodes.Add(prefabNode); 

      _prefabs.Add(prefab); 
     } 
    } 

而且here's创建和调用:

  _flagSystem.AddFlag("PrefabManager", new PrefabManager(tpage_prefabs_tree)); 
      //... 
      _flagSystem.GetFlag<PrefabManager>("PrefabManager").LoadPrefabs(); 

错误习惯这里造成的:

//LoadPrefabs-Method: 
categoryNode.Nodes.Add(prefabNode); 

您认为是什么问题?我不相信这是一个线程问题。 我该如何解决这个问题?

感谢很多:)

编辑 糟糕了,没有人知道答案:( 顺便说一句,这里是堆栈跟踪以及有关异常的一些信息:

bei System.Windows.Forms.TreeNode.Realize(Boolean insertFirst) 
bei System.Windows.Forms.TreeNodeCollection.AddInternal(TreeNode node, Int32 delta) 
bei System.Windows.Forms.TreeNodeCollection.Add(TreeNode node) 
bei GooEditor.Prefabs.PrefabManager.GetCategoryOrCreate(String category) in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Prefabs\PrefabManager.cs:Zeile 87. 
bei GooEditor.Prefabs.PrefabManager.LoadPrefabs() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Prefabs\PrefabManager.cs:Zeile 40. 
bei GooEditor.EditorForm.LoadContent() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\EditorForm.cs:Zeile 202. 
bei GooEditor.Editor.LoadContent() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Editor.cs:Zeile 117. 
bei Microsoft.Xna.Framework.Game.Initialize() 
bei GooEngine.Core.Application.Initialize() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEngine\Core\Application.cs:Zeile 85. 
bei Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun) 
bei Microsoft.Xna.Framework.Game.Run() 
bei XNAViewer.XNAViewer.StartGameLoop(Object game) 
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
bei System.Threading.ThreadHelper.ThreadStart(Object obj) 

{“Derfürdieses SteuerelementdurchgeführteVorgang wird vom falschen Thread aufgerufen。Marshallen Sie den richtigen Thread mit Control.Invoke oder Control.BeginInvoke,um den Vorgangauszuführen。”}

译文)对此控制操作执行的测试是从错误的线程调用的。封送正确的线程或用Control.Invoke Control.BeginInvoke执行操作

回答

1

错误,抱歉。现在我得到了解决方案。

我刚刚以错误的方式调用 - 所以它没有工作。在这里,我找到了,这表明我如何工作的:Thread Control.Invoke

这里的样本:

_tree.Invoke((MethodInvoker) (() => categoryNode.Nodes.Add(prefabNode))); 
+0

我总是忘记这一点,在我来说,我使用'如果(InvokeRequired()){调用((MethodInvoker) (()=> categoryNode.Nodes.Add(newNode))); } else {categoryNode.Nodes.Add(newNode); }' – 2016-08-02 20:42:17

相关问题