[英]How can I use async in C# to get the result I need from a python script called as a process?
I have built a GUI using C# .NET and I need to incorporate a Python script to be called if a checkbox is selected on the panel when the "PROCEED" button is clicked.我已经使用 C# .NET 构建了一个 GUI,如果单击“PROCEED”按钮时在面板上选择了一个复选框,我需要合并一个 Python 脚本来调用。 The python script should run in the background and then I'd like to print the string result in a message box at the end of the main process launched by the GUI.
python 脚本应该在后台运行,然后我想在 GUI 启动的主进程结束时在消息框中打印字符串结果。 The important thing is that I only want the message box to pop up if the checkbox was selected.
重要的是,我只希望在选中复选框时弹出消息框。
I understand how I can call Python from C#, but I am still a bit fuzzy on how I can collect and display the result using an async function.我了解如何从 C# 调用 Python,但对于如何使用异步函数收集和显示结果仍然有些模糊。 I understand based on Microsoft docs that I need to use the Task object, but I cannot quite get this to function the way I am intending.
我根据 Microsoft 文档了解我需要使用 Task 对象,但我无法完全按照我的预期方式运行它。 Here are the docs I used in my code so far for reference: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
以下是迄今为止我在代码中使用的文档以供参考: https ://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
This is my first time using async in C#.这是我第一次在 C# 中使用异步。
Here is my code for the relevant functions(shortened for clarity), and then I will describe the issues in detail with questions:下面是我的相关函数代码(为了清楚起见,缩短了),然后我将用问题详细描述问题:
async private void proceedClicked()
{
if (checkBox.Checked)
{
string cmd = ""; // some python command
Task<string> pythonTask = runProcAsync(cmd);
}
// do some other processing
if (checkBox.Checked)
{
var pythonResult = await pythonTask;
// print result to a message box
}
}
private Task runProcAsync(string cmd)
{
return Task.Run(() =>
{
callPython(cmd);
});
}
private string callPython(string cmd)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "python.exe";// full path to python
start.Arguments = cmd;
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return result;
}
}
}
Here are my issues with some details about my implementation approaches:以下是关于我的实现方法的一些细节的问题:
Thanks in advance for the advice/assistance!提前感谢您的建议/帮助!
Apart from the issue around returning the result, you should not use blocking functions in async code.除了返回结果的问题外,您不应该在异步代码中使用阻塞函数。 Instead use async all the way:
而是一直使用异步:
async private void proceedClicked()
{
if (checkBox.Checked)
{
string cmd = ""; // some python command
Task<string> pythonTask = runProcAsync(cmd);
}
// do some other processing
if (checkBox.Checked)
{
var pythonResult = await pythonTask;
// print result to a message box
}
}
private async Task<string> runProcAsync(string cmd)
{
ProcessStartInfo start = new ProcessStartInfo
{
FileName = "python.exe", // full path to python
Arguments = cmd,
UseShellExecute = false,
RedirectStandardOutput = true,
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = await reader.ReadToEndAsync();
return result;
}
}
}
private Task runProcAsync(string cmd)
{
return Task.Run(() =>
{
callPython(cmd);
});
}
Should probably be:应该是:
private Task<string> runProcAsync(string cmd)
{
// you should be able to omit <string> here, as long as the return type is explicitly a string
return Task.Run<string>(() =>
{
return callPython(cmd);
});
}
Feel free to review some of Microsoft's documentation on Task
s here and here , and their guide to Task-based asynchronous programming .随意查看 Microsoft 的一些关于
Task
的文档, 这里和这里,以及他们的基于任务的异步编程指南。
I noticed you are also trying to use Task.Result
as if it were a method, when in fact it is a property of the Task
class.我注意到您还尝试将
Task.Result
用作方法,而实际上它是Task
类的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.