等待进程结束异步,然后在主窗体内调用一个函数 [英] Wait for process to end async and then call a function within the main form

查看:106
本文介绍了等待进程结束异步,然后在主窗体内调用一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用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节点指向的File的完整路径的字符串. DisplayText()从节点指向的文件中读取文本,并将其显示在富文本框中.

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

如何创建一个以异步方式退出函数时以我的主要形式调用函数的进程?我知道当我使用WaitForExit()函数时它可以工作,但是随后我的窗体冻结并等待直到记事本关闭.我希望用户能够使用编辑器打开其他txt文件,并且当一个编辑器关闭时,我的GUI中正在更新richtextbox文本ist.

/编辑/ 现在解决. 感谢伍德曼的回答,我替换了

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

使用

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

解决方案

由于只允许从UI线程访问UI对象,因此应在NotePadHasEnded()方法内使用Dispatcher.InvokeDispatcher.BeginInvoke切换到UI线程./p>

查看这篇文章以获得更多详细信息.

>

I'm coding an editor for a game with C#. My programm openes as .txt File by starting a notepad.exe process. If that process exits, I want to call a function within the main form (to update the textbox). Here's what I'm doing so far:

 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;
    }

The GetRealPathByNode() function returns a string of the full path of the File which the TreeView node points at. DisplayText() reads the text from the file the node points at and displays that in a richtextbox.

Upon executing, my main form is still usable as I wanted it, but when the process is terminated (notepad closed), it throws an error stating that the function NotePadHasEnded has no access to the treeView1 object because it is being executed in another process.

How can I create a process that calls a function in my main form when it is being exited, asynchronously? I know that it works when I use the WaitForExit() function, but then my Form freezes and waits until notepad closes. I want the user to be able to open up other txt files with the editor and when one editor is being closed that the richtextbox text ist being updated in my GUI.

/Edit/ Now Solved. Thanks to Woodman's answer, I replaced

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

with

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

解决方案

You should use Dispatcher.Invoke or Dispatcher.BeginInvoke inside NotePadHasEnded() method to switch to UI thread as you only allowed to access UI objects from UI thread.

Check this post for further details.

这篇关于等待进程结束异步,然后在主窗体内调用一个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆