我想启动一个进程,而不是等待它完成
但是,当进程退出时,我想调用另一个进程并将参数传递给它。
我可以用已知的函数这样做:
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"));