Windows进程退出后,如何将参数传递给动态函数



我想启动一个进程,而不是等待它完成
但是,当进程退出时,我想调用另一个进程并将参数传递给它。

我可以用已知的函数这样做:

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

如何传递对函数的引用并包含该函数的参数?

使用方法delegate的变体,以防委托在处理completion字符串时需要返回一些东西
我已经添加了EventArgs参数,因为这是您的问题,但我看不出这怎么有用。你可以在这里忽略它。

您也可以在没有delegate声明的情况下执行此操作,只需传递:

Func<object, EventArgs, string, string> completionFunc

而不是CCD_ 6方法中的CCD_。


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参数将是执行RunCommand方法时的completion字符串值。

这允许三种不同的方法调用:

内衬

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)

您可以在方法中添加一个额外的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"));

最新更新