/// <summary> /// run the python code in a task /// </summary> private void RunTask() { PythonRunResult result = new PythonRunResult(); Task task = Task.Factory.StartNew(() => { result = RunProcess(); //remove the custom output allowing us to extract variables from python CleanStdout(); if (runInBackground) { onTaskEnd?.Invoke(this, result); } }); if (!runInBackground) { task.Wait(); onTaskEnd?.Invoke(this, result); } }
/// <summary> /// convert the string received from python to a PythonRunResult /// </summary> /// <param name="result">output of stdout</param> /// <param name="error">output of stderr</param> /// <returns></returns> private PythonRunResult InterpretResult(string result, string error) { //first check if there is and error if so stop if (!string.IsNullOrWhiteSpace(error)) { //return run result with the traceback python gave us return(new PythonRunResult() { hasError = true, errorString = error }); } //if the result (stdout) is empty then something wrong happened //same if the result doesn't contain what our custom code printed if (string.IsNullOrWhiteSpace(result) || !result.Contains("ENDUSEROUTPUT")) { //no stdout that means the process was killed before finishing //or if there is no "ENDUSEROUTPUT" that means out custom code didn't have time to run return(new PythonRunResult() { hasError = true, errorString = "the python process was killed" }); } //from there on we are sure the process finished sucessfully //split where the python printed "ENDUSEROUTPUT", this should only have been printed once //therefore the string[] should only have 2 elements in it string[] resultArr = result.Split(new string[] { "ENDUSEROUTPUT" }, StringSplitOptions.None); //if it doesn't have only 2 elements that means the user printed "ENDUSEROUTPUT" himself (weirdo) if (resultArr.Length != 2) { //return run result with custom error message PythonRunResult pythonRunResult = new PythonRunResult() { hasError = true, errorString = "You can't print \"ENDUSEROUTPUT\", or an unexpected case happened" }; return(pythonRunResult); } else { //return run result without and error and a hashtable filled with the extracted variables Dictionary <string, object> table = new Dictionary <string, object>(); //the output will look something like this : "outVal1=5|outVal2=value" //each var is separated by a | string[] vars = resultArr[1].Split('|'); for (int i = 0; i < vars.Length; i++) { string[] thisVar = vars[i].Split('='); //thisVar[0] = varName //thisVar[1] = varValue table.Add(thisVar[0], TryConvert(thisVar[1])); } PythonRunResult pythonRunResult = new PythonRunResult() { hasError = false, returnedValues = table }; return(pythonRunResult); } }