2017-07-19 22 views
0

我遇到了以下问题:我有一个配置文件和一个侦听器来覆盖此文件。当更改时,触发方法(createMenuAndItems),修改toolStripMenuItem动态创建toolStripMenuItem时出错

方法createMenuAndItems在窗体的加载和配置文件被修改时被调用。每当阵列

strArrays = new string[] { "Copy File" , "Exit"}; 

有多个项目,当我修改配置文件时显示错误。在加载表单工作正常。

该错误作为在Visual Studio中所示:

System.InvalidOperationException了未处理

的HResult = -2146233079
消息=:跨线程操作无效:控制 'TopMenu中' 访问来自其创建的线以外的线程

实际消息是

消息=Operación没有válida一个través德subprocesos:硒tuvo acceso人控制 'TopMenu中' desde未subproceso distinto一个aquel烯阙LO CREO。

源= System.Windows.Forms的
堆栈跟踪:

试图与CheckForIllegalCrossThreadCalls = False;但没有运气

奇怪的是,如果阵列strArrays只有一个价值,它就像一个魅力。但是当添加更多的项目开始显示此错误

这是代码。

监听器在文件:

private void configWatcher() 
    { 
     FileSystemWatcher fileSystemWatcher = new FileSystemWatcher() 
     { 
      Path = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "\\Launcher"), 
      Filter = "Config.xml" 
     }; 
     fileSystemWatcher.Changed += new FileSystemEventHandler(this.createMenuAndItems); 
     fileSystemWatcher.EnableRaisingEvents = true; 
    } 

下面是一个创建和修改toolStripMenuItem

private void createMenuAndItems() 
{ 
    string str; 
    ToolStripMenuItem toolStripMenuItem; 
    int i; 
    base.Invoke(new Action(() => 
    { 
     base.Controls.Find("topMenu", false); 
     if (base.Controls.IndexOfKey("topMenu") > 0) 
     { 
      base.Controls.RemoveByKey("topMenu"); 
     } 
    })); 
    MenuStrip menuStrip = new MenuStrip() 
    { 
     Name = "topMenu" 
    }; 
    base.Invoke(new Action(() => this.Controls.Add(menuStrip))); 
    string[] strArrays = new string[] { "Menú" }; 
    string[] array = strArrays; 
    for (i = 0; i < (int)array.Length; i++) 
    { 
     ToolStripMenuItem toolStripMenuItem1 = new ToolStripMenuItem(array[i]); 
     menuStrip.Items.Add(toolStripMenuItem1); 
    } 
    foreach (ToolStripMenuItem item in menuStrip.Items) 
    { 
     if (item.Text == "Menú") 
     { 
      strArrays = new string[] { "Copy File" , "Exit"}; 
      array = strArrays;      
      for (i = 0; i < (int)array.Length; i++) 
      { 
       str = array[i]; 
       toolStripMenuItem = new ToolStripMenuItem(str, null, new EventHandler(this.ChildClick)); 
       item.DropDownItems.Add(toolStripMenuItem); 
      } 
      foreach (ToolStripMenuItem dropDownItem in item.DropDownItems) 
      { 
       if (dropDownItem.Text == "Copy File") 
       { 
        //gives a list of strings. 
        array = this.fetchServersFromConfig().ToArray(); 
        for (i = 0; i < (int)array.Length; i++) 
        { 
         str = array[i]; 
         toolStripMenuItem = new ToolStripMenuItem(string.Concat("Origin: ", str), null, new EventHandler(this.copyFile)); 
         dropDownItem.DropDownItems.Add(toolStripMenuItem); 
        } 
       } 
       if (dropDownItem.Text == "Exit") 
       {        
        dropDownItem.ShortcutKeys = Keys.Control | Keys.Q; 
        dropDownItem.Click += new EventHandler(this.exitButtonMenu); 
       } 
      } 
     } 
    } 
} 

感谢代码!

fileSystemWatcher.Changed += new FileSystemEventHandler(base.Invoke(new Action(() => this.createMenuAndItems()));); 

相反的:

+0

非常确信**任何菜单项的创建**也应该在主UI线程上完成。 –

回答

1

最后通过的configWatcher()

内主线程像这样调用菜单和项目的创新解决了这个

fileSystemWatcher.Changed += new FileSystemEventHandler(this.createMenuAndItems);