C# 停止进程阻塞UI并在事件发生时返回事件
我正在尝试运行一个脚本,并在日志文件中获得输出。但是,当我运行该事件时,它会阻塞UI并等待到结束,并吐出所有输出。理想情况下,我希望它是实时的C# 停止进程阻塞UI并在事件发生时返回事件,c#,.net,winforms,C#,.net,Winforms,我正在尝试运行一个脚本,并在日志文件中获得输出。但是,当我运行该事件时,它会阻塞UI并等待到结束,并吐出所有输出。理想情况下,我希望它是实时的 public static void ExecuteCommandSync(object command) { try { System.Diagnostics.ProcessStartInfo procStartInfo =
public static void ExecuteCommandSync(object command)
{
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
Log.addLog(result);
}
catch (Exception objException)
{
Log.addLog(objException.Message);
}
}
您可以完全异步:
public static async Task<string> ExecuteCommandAsync(object command)
{
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
return await proc.StandardOutput.ReadToEndAsync();
}
catch (Exception objException)
{
return objException.Message;
}
}
如果没有更详细的问题,就不可能确切地知道你需要什么建议。但是,您写下您希望“在日志文件中获得输出”,这在我看来似乎意味着您不希望等到进程退出后才将输出写入日志文件,而是希望在输出发生时记录输出 如果是这样,您需要使用
进程
类及其关联流或读卡器可用的许多异步I/O机制之一
例如:
public static async Task ExecuteCommandAsync(object command)
{
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
await ConsumeReader(proc.StandardOutput);
}
catch (Exception objException)
{
Log.addLog(objException.Message);
}
}
async static Task ConsumeReader(TextReader reader)
{
string text;
while ((text = await reader.ReadLineAsync()) != null)
{
Log.addLog(text);
}
}
上面的代码将异步地将输出写入日志文件,并提供进程完成时的异步通知。当然,要使后者起作用,您需要等待调用ExecuteCommandAsync()
。如果您不需要流程完成的通知,那么您可以只保留方法签名(即使其简单地静态无效
),然后忽略ConsumerReader()返回的任务
对象
如果上面的内容不能解决您的问题,那么请提供一个很好的示例,清楚地显示您正在尝试做什么,并精确地描述代码的作用以及您希望它做什么,从而改进问题
还请注意,关于异步使用进程
输出,以及关于一般避免阻塞UI线程,在堆栈溢出方面已经存在许多问题。您可能可以通过在网站上搜索这些主题来查找更多详细信息
public static async Task ExecuteCommandAsync(object command)
{
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
await ConsumeReader(proc.StandardOutput);
}
catch (Exception objException)
{
Log.addLog(objException.Message);
}
}
async static Task ConsumeReader(TextReader reader)
{
string text;
while ((text = await reader.ReadLineAsync()) != null)
{
Log.addLog(text);
}
}