我已經使用 C# .NET 構建了一個 GUI,如果單擊“PROCEED”按鈕時在面板上選擇了一個復選框,我需要合并一個 Python 腳本來呼叫。python 腳本應該在后臺運行,然后我想在 GUI 啟動的主行程結束時在訊息框中列印字串結果。重要的是,我只希望在選中復選框時彈出訊息框。
我了解如何從 C# 呼叫 Python,但對于如何使用異步函式收集和顯示結果仍然有些模糊。我根據 Microsoft 檔案了解我需要使用 Task 物件,但我無法完全按照我的預期方式運行它。以下是迄今為止我在代碼中使用的檔案以供參考:https ://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
這是我第一次在 C# 中使用異步。
下面是我的相關函式代碼(為了清楚起見,縮短了),然后我將用問題詳細描述問題:
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;
}
}
}
以下是關于我的實作方法的一些細節的問題:
- 如何對齊 Task 和 Task 物件以使它們匹配?我嘗試使用 Task 然后 Task.Result() 來獲取字串,但是 Result() 不作為我宣告的 Task var 的方法存在。然后我嘗試使用 Task<> 作為型別,但是 Task.Run() 抱怨隱式轉換,因為它不受支持并且必須是顯式的。(對于我的第二種方法,字串應該在那些克拉中,但是格式阻止了我和 IDK 如何修復它)。
- 如何宣告 Task 物件,使其出現在兩個條件范圍內?我嘗試在外部范圍內使用建構式宣告它,并且該物件沒有建構式。我可以在沒有建構式的情況下在外部作用域中宣告變數,但是在第二個作用域中出現錯誤,即在第一個作用域中賦值后變數未賦值。我的直覺告訴我在外部范圍內將其宣告為 none,在第一個條件塊中賦值,然后在第二個條件塊中檢查除 none 以外的值。
- 我對 async/await 的使用是否合適/正確,還是有更好的方法?由于我正在呼叫一個行程,這將如何影響異步的使用?
提前感謝您的建議/幫助!
uj5u.com熱心網友回復:
除了回傳結果的問題外,您不應該在異步代碼中使用阻塞函式。而是一直使用異步:
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;
}
}
}
uj5u.com熱心網友回復:
private Task runProcAsync(string cmd)
{
return Task.Run(() =>
{
callPython(cmd);
});
}
應該是:
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);
});
}
隨意查看 Microsoft 的一些關于Tasks這里和這里的檔案,以及他們的基于任務的異步編程指南。
我注意到您還試圖將Task.Result其用作方法,而實際上它是Task該類的屬性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/498341.html
