結論: C#與python是獨立運行, 所以兩者之間有更多更有效率的方法, 甚至可以將資料檔上傳後, 再通知python執行運算, 之後選擇定時監控或自行固定一段時間去察看是否生成完成檔, 在客戶端也不用佔住畫面等待執行完成.
兩種方式, 一種是透過安裝IronPython, 另一種是直接使用python.exe執行檔
IronPython程式好撰寫, 但是model引用一直失敗, 所以最後就沒再嘗試
下面操作方法是將參數傳遞給python, 於python以print方式將計算結果顯示出來, 再於c#使用StreamReader讀取顯示的結果.
[直接呼叫python執行檔]
1. 安裝python開發平台: Anaconda 3 (python版本: 3.7.4)
2. 設定環境變數:
需設定3個環境變數, 若系統沒有設定環境變數, 會造成在import model時, 無法正確找到model.
控制台>系統及安全性>系統>進階系統設定>環境變數 >[系統變數] 點選path 添加變數
3.程式碼
(1) c#
private void call_python()
{
System.Diagnostics.ProcessStartInfo py_process = new System.Diagnostics.ProcessStartInfo();
//python interprater location
py_process.FileName = @"C:\ProgramData\Anaconda3\python.exe"; //調用python.exe
string pyPath = Server.MapPath("main.py");
string parameters = " and 5 10";//以空格分隔參數
py_process.Arguments = pyPath + parameters; //檔名後面加要計算的傳遞參數
py_process.UseShellExecute = false;// Do not use OS shell
py_process.CreateNoWindow = true; // We don't need new window
py_process.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
py_process.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
py_process.LoadUserProfile = true;
using (System.Diagnostics.Process process = System.Diagnostics.Process.Start(py_process))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd();
string result = reader.ReadToEnd();
Debug.Print(result);
}
}
}
(2) py
try:
import pandas as pd
except:
print("model import error!")
import sys
if __name__ == '__main__':
try:
df= pd.read_csv('d:/py/test.csv')
print(df)
except:
print("function error!")
4.執行結果
5. 透過傳遞參數回傳結果
(1)C#
(2)main.py
try:
import sys
import multi
from pandas import DataFrame,Series
except:
print("model import error!")
if __name__ == '__main__':
if sys.argv[1]=='and':
try:
result=multi.calculation(int(sys.argv[2]),int(sys.argv[3]))
except:
print("function error!")
(3)multi.py
def calculation(a,b):
return a*b
1.在呼叫python執行py檔時, 若py檔內沒有使用try except, 若發生錯誤不會有任何訊息, 只會無法顯示回傳的資料, 這點要注意.
2.環境變數沒有設定會造成model import時出錯
3.在Jupyter下可正常運行python不代表在C# call python也能正常運行.
Debug
1.爬蟲時出現錯誤
在Jupyter下執行正常, 但是在C# call python就出錯.
使用r = requests.request(url) 讀取網頁, 並用try: except :requests.exceptions.RequestException as e:, 讀書報錯如下:
HTTPSConnectionPool(host='www.xxx.com', port=443): Max retries exceeded with url: /title/tt4154796 (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available."))
使用df = pd.read_html(url)一樣錯誤
後來用最原始的方式開python.exe 執行python, 出現下列訊息:
D:\>python main.py
Traceback (most recent call last):
File "main.py", line 3, in <module>
dfs = pd.read_html(url)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\html.py", line 1105, in read_html
displayed_only=displayed_only,
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\html.py", line 912, in _parse
raise_with_traceback(retained)
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\compat\__init__.py", line 46, in raise_with_traceback
raise exc.with_traceback(traceback)
urllib.error.URLError: <urlopen error unknown url type: https>
最後成功的方法, 把Anaconda3\Library\bincopy資料夾內的libssl-1_1-x64.dll複製到資料夾Anaconda3\DLLs目錄下, 就能成功執行.
也選Jupyter等開發平台有整合這些好, 若在c# call python就要多注意這些細節, 還是需要用最原始的執行方法確認python程式是否正確.
另外使用type(dfs)確認讀取的資料為list, 所以需要將list轉成string, 不能直接print錯誤.
dt=pd.DataFrame(data=df)
所以最好就是把檔案存成csv檔, 再由c#載入.
留言列表