2013-02-23 112 views
0

我使用C#编写了一款游戏编辑器。我的程序通过启动notepad.exe进程打开.txt文件。如果该进程退出,我想在主窗体中调用一个函数(以更新文本框)。 下面是我在做什么至今:等待进程结束异步,然后调用主表单中的函数

void OpenTextEditor(TreeNode node) 
    { 
     Process editor = new Process(); 
     editor.StartInfo.WorkingDirectory = "%WINDIR%"; 
     editor.StartInfo.FileName = "notepad.exe"; 
     var txtfilelocation = GetRealPathByNode(node); 
     var txtfile = File.ReadAllText(txtfilelocation,Encoding.Default); 
     txtfile = txtfile.Replace("\n", "\r\n"); 
     File.WriteAllText(txtfilelocation,txtfile,Encoding.Default); 
     editor.StartInfo.Arguments = txtfilelocation; 
     editor.EnableRaisingEvents = true; 
     editor.Exited += delegate { 
      NotePadHasEnded(node); 
     }; 
     editor.Start(); //starten 
    } 

    public Delegate NotePadHasEnded(TreeNode node) 
    { 
     var txtfilelocation = GetRealPathByNode(node); 
     var newfileloc = txtfilelocation; 
     var newfile = File.ReadAllText(newfileloc, Encoding.Default); 
     newfile = newfile.Replace("\r\n", "\n"); 
     File.WriteAllText(txtfilelocation, newfile, Encoding.Default); 

     if (treeView1.SelectedNode == node) DisplayText(node); 

     return null; 
    } 

的GetRealPathByNode()函数返回文件,TreeView的节点点的完整路径的字符串。 DisplayText()从节点指向的文件中读取文本,并将其显示在richtextbox中。

执行后,我的主窗体仍然可以使用,但是当进程终止(记事本关闭)时,它会抛出一个错误,指出NotePadHasEnded函数无法访问treeView1对象,因为它正在执行在另一个过程中。

如何创建一个在我的主窗体中以异步方式退出时调用函数的进程?我知道它在我使用WaitForExit()函数时有效,但是我的表单冻结并等待记事本关闭。我希望用户能够使用编辑器打开其他txt文件,并且当一个编辑器关闭时,richtextbox文本将在我的GUI中进行更新。

/编辑/ 现已解决。 由于樵夫的回答,我换成

  editor.Exited += delegate { 
      NotePadHasEnded(node); 
      }; 

editor.Exited += delegate 
     { 
      this.Invoke((MethodInvoker)delegate() 
      { 
       NotePadHasEnded(node); 
      }); 
     }; 

回答

0

您应该使用Dispatcher.InvokeDispatcher.BeginInvokeNotePadHasEnded()方法切换到UI线程,你只能从UI线程访问UI对象。

查询this post了解更多详情。

+0

我爱你:) 有了这个职位,你报我简单使用的代码片断 this.Invoke((MethodInvoker)委托(){ NotePadHasEnded(节点); }); 在窗体内调用函数。 现在工作代码: 编辑。退出+ =委托 { this.Invoke((MethodInvoker)delegate() { NotePadHasEnded(node); }); 这一切都是它花了。谢谢。 – 2013-02-23 14:31:54

0

Exited事件发生在另一个thead,你只能访问他们自己的线程(这称为UI线程)的UI控件。由于您使用的是Windows窗体,你应该使用Control.Invoke方法:

editor.Exited += delegate 
{ 
    node.TreeView.Invoke(new Action<TreeNode>(NotePadHasEnded), node); 
}; 

也改变了NotePadHasEnded的返回类型void

node.TreeView用于访问Invoke方法。您可以使用任何UI控件。如果代码驻留在表单中,则可以使用this