2013-02-23 111 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