项目场景:
?????????今天写程序的时候遇到了一个问题,C#使用Process调用Python脚本时怎么弄都不能异步输出,都是等程序执行完了才输出结果,头疼了一晚上,试了好多人的c#代码都不行,所幸发现了这个老哥的帖子(C# 通过控制台调用 python 不能异步获取控制台信息_博问_博客园 (cnblogs.com)),最后解决了,这里我自己记录一下这个问题,也为后来人提供一下帮助。
问题描述:
C#使用Process调用Python脚本时不能异步输出
原因分析:
参考了这个老哥C# 通过控制台调用 python 不能异步获取控制台信息_博问_博客园 (cnblogs.com)
解决方案:
其实是python的问题,python默认缓冲区满了才会输出, 运行时加 -u 参数就可以立即输出了。
这里放上我的源码作为参考:
c#:
using Microsoft.Scripting.Hosting;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace MonkeyWinForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Process p = new Process();
string path = "-u aa.py";//待处理python文件的路径,本例中放在debug文件夹下
string sArguments = path;
ArrayList arrayList = new ArrayList();
arrayList.Add("1");
arrayList.Add("2");
foreach (var param in arrayList)//添加参数
{
sArguments += " " + param;
}
p.StartInfo.FileName = @"D:\anaconda\python.exe"; //python的安装路径
p.StartInfo.Arguments = sArguments;//python命令的参数
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.EnableRaisingEvents = true;// 启用Exited事件
p.Exited += new EventHandler(CmdProcess_Exited);
p.Start();//启动进程
p.BeginOutputReadLine();
//p.WaitForExit();
p.Close();
Console.WriteLine("执行完毕!");
}
public void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
string line;
try
{
if (outLine.Data != null)
{
line = (outLine.Data.ToString());
//在外部函数给Form赋值必须这样
Invoke(new Action(() =>
{
labelResult.Text += line;
labelResult.Text += "\r\n";
}));
Console.WriteLine(line);
}
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
private void CmdProcess_Exited(object sender, EventArgs e)
{
// 执行结束后触发
}
}
}
用于测试的python:
import numpy as np
import sys
import time
def resetIPC(arg1, arg2):
a = int(arg1)
b = int(arg2)
result = a+b
return result
print(resetIPC(sys.argv[1], sys.argv[2]))
#time.sleep(1)
print(resetIPC("4", sys.argv[2]))
time.sleep(1)
print(resetIPC(sys.argv[1], sys.argv[2]))
time.sleep(3)
print(resetIPC(sys.argv[1], sys.argv[2]))
|