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()は、ノードが指すファイルからテキストを読み取り、それをリッチテキストボックスに表示します。

実行すると、メインフォームは希望どおりに使用できますが、プロセスが終了すると(メモ帳が閉じられる)、別のプロセスで実行されているため、関数NotePadHasEndedがtreeView1オブジェクトにアクセスできないことを示すエラーがスローされます。

非同期で終了するときにメインフォームの関数を呼び出すプロセスを作成するにはどうすればよいですか?WaitForExit()関数を使用すると機能することはわかっていますが、フォームがフリーズし、メモ帳が閉じるまで待機します。ユーザーがエディターで他のtxtファイルを開くことができ、1つのエディターが閉じられているときに、GUIでリッチテキストボックスのテキストが更新されないようにしたいと思います。

/編集/解決しました。ウッドマンの答えのおかげで、私は交換しました

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

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

3 に答える 3

0

UIスレッドからのUIオブジェクトへのアクセスのみが許可されているため、メソッド内Dispatcher.Invokeまたはメソッドを使用してUIスレッドに切り替える必要があります。Dispatcher.BeginInvokeNotePadHasEnded()

詳細については、この投稿を確認してください。

于 2013-02-23T14:15:53.337 に答える
0

GoogleforSynchronizationContext 。_ このエラーは、UIスレッドが実行中の2番目のスレッドと同期されていないために発生し、その後エディターが閉じられました。同期を実装する方法を説明するいくつかの例を見つけました。それは、SynchronizationContextとExecutionContextとSynchronizationContextのすべてです。これがお役に立てば幸いです;-)

于 2013-02-23T14:16:36.063 に答える
0

イベントは別のExitedスレッドで発生し、独自のスレッド (UI スレッドと呼ばれる) でのみ UI コントロールにアクセスできます。Windows フォームを使用しているため、次のControl.Invoke方法を使用する必要があります。

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

また、 の戻り値の型を に変更NotePadHasEndedvoidます。

node.TreeViewメソッドにアクセスするために使用されますInvoke。任意の UI コントロールを使用できます。コードがフォームにある場合は、this代わりに使用できます。

于 2013-02-23T14:30:17.603 に答える