Как передать параметры динамической функции после завершения процесса Windows? - PullRequest
0 голосов
/ 30 декабря 2018

Я хочу запустить процесс, а не ждать его завершения.
Однако, когда процесс завершается, я бы хотел вызвать другой процесс и передать ему параметры.

Я могу это сделатьс известной функцией, подобной этой:

public static void RunCommand(string path, string parms, string completion)
{
    Process myProc = new Process();

    myProc.StartInfo.FileName = path;
    myProc.StartInfo.Arguments = parms;
    myProc.EnableRaisingEvents = true;
    myProc.StartInfo.UseShellExecute = false;
    myProc.Exited += (sender, ex) => CommandExecuted(sender, ex, completion);
    myProc.Start();
}

private static void CommandExecuted(object sender, System.EventArgs e, string completion)
{
    //do stuff with "completion" string
}

Что я хотел бы сделать, это передать другую функцию во время выполнения, а не известную функцию CommandExecuted.

Как передать ссылку на функцию и включить параметры для этой функции?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Вариант с использованием делегата метода, в случае, если делегату нужно что-то вернуть, когда он обрабатывает строку completion.
Я добавил параметр EventArgs, так как он в вашем вопросе, но я нене вижу, как это может быть полезно.Вы можете проигнорировать это здесь.

Вы также можете сделать это без объявления delegate и просто передать:

Func<object, EventArgs, string, string> completionFunc

вместо параметра CompletionFunc completionFunc вRunCommand метод.


public delegate string CompletionFunc(object o, EventArgs e, string s);

public static void RunCommand(string path, string parms, string completion, CompletionFunc completionFunc)
{
    string result = string.Empty;
    Process myProc = new Process();

    myProc.StartInfo.FileName = path;
    myProc.StartInfo.Arguments = parms;
    myProc.EnableRaisingEvents = true;
    myProc.StartInfo.UseShellExecute = false;
    myProc.Exited += (obj, evt) => {
        result = completionFunc(obj, evt, completion);
        Console.WriteLine($"{result} ExitCode: {myProc.ExitCode})");
        if (myProc != null) myProc.Dispose();
    };
    myProc.Start();
}

Вызов метода RunCommand.
В качестве теста я использую tracert.exe для отслеживания IP-адреса (для завершения требуется некоторое время).
Метод RunCommand выполняется асинхронно и выводит на консоль свои результаты при возникновении события Exited.

Параметр str здесь будет строковым значением completion, когда RunCommand метод выполняется.

Это позволяет три различных вызова метода:

Встроенный :

string completion = "[Some Data]";

RunCommand("tracert.exe", "[Some IP Address]", completion, (obj, evt, str) => {
    return $"Completion: {str + " : Completed"} " +
           $"Process: {((Process)obj).StartInfo.FileName} " +
           $"Result: {"Some result"}";
});

Использование локальной функции :

private void SomeStartingMethod()
{
    string MethodCall(object obj, EventArgs evt, string str)
    {
        return $"Completion: {str + " : Completed"} " +
               $"Process: {((Process)obj).StartInfo.FileName} " +
               $"Result: {"Some result"}";
    }

    string completion = "[Some Data]";
    RunCommand("tracert.exe", "[Some IP Address]", completion, MethodCall);
}

Используя метод, который соответствует подписи делегата :

string MethodCall2(object obj, EventArgs evt, string str)
{
    return $"Completion: {str + " : Completed"} " +
           $"Process: {((Process)obj).StartInfo.FileName} " +
           $"Result: {"Some result"}";
}


// Somewhere else
string completion = "[Some Data]";
RunCommand("tracert.exe", "[Some IP Address]", completion, MethodCall2);

Все это будет печатать:

Completion: [Some Data] : Completed Process: tracert.exe Result: Some result ExitCode: 0)
0 голосов
/ 30 декабря 2018

Вы можете добавить дополнительный параметр Action в свой метод - Action - это переменная, представляющая метод без возвращаемого типа.Поэтому, если вы измените свое объявление на:

public static void RunCommand(string path, string parms, string completion, 
    Action<object, EventArgs, string> exitedCallback)
{
    Process myProc = new Process();

    myProc.StartInfo.FileName = path;
    myProc.StartInfo.Arguments = parms;
    myProc.EnableRaisingEvents = true;
    myProc.StartInfo.UseShellExecute = false;
    myProc.Exited += (o, e) => exitedCallback(o, e, completion);
    myProc.Start();
}

Так что теперь, даже во время выполнения, вы можете передать любой метод, который соответствует подписи:

RunCommand("1.exe", string.Empty, string.Empty, CommandExecuted);
RunCommand("1.exe", string.Empty, string.Empty, (o, e, c) => Console.WriteLine("Foo"));
...