我有一些从 C# 解决方案执行的 Python 代码。除了这一件事之外,一切都运行良好,考虑到 Python 默认情况下应该是同步的,这对我来说毫无意义。
函数调用完成后,作为 Python 代码入口点的文件就会结束。基本上是这样的:
if __name__ == '__main__':
# CODE OMITTED - setting up variables using command-line arguments received
try:
my_function(var1, var2, var3)
except RuntimeError as codedErr:
print('ERROR: ' + str(codedErr))
raise SystemExit(0)
我知道错误处理有点奇怪,但我的 C# 解决方案是读取输出流以查看执行结果。
无论如何,my_function 做了很多事情,但它的结局是这样的:
if my_cool_list is None or len(my_cool_list) < len(original_objects):
logger.warning('Full execution was not possible with the selected parameters.')
print('Full execution was not possible with the selected parameters.')
data.set_execution_result(object_id, "NP")
else:
# CODE OMITTED - 3 different SQL-related function calls in the 'data' file
data.set_execution_result(object_id, "O")
data.set_execution_progress_pct(99)
return
最后,文件中的set_execution_progress_pct函数
data.py
看起来像这样:
def set_execution_progress_pct(progress_pct):
logger.debug(f'Attempting to update progress of execution with ID={cfg.executionRequestId} to {progress_pct}%.')
connString = get_connection_string()
conn = pyodbc.connect(connString)
cursor = conn.cursor()
sql = f"UPDATE ExecutionRequest SET Progress='{progress_pct}' WHERE ID='{cfg.executionRequestId}'"
result = cursor.execute(sql)
cursor.commit()
if result.rowcount != 1:
logger.error('Failed to update progress on Execution Requests table.')
else:
logger.info('Progress updated.')
cursor.close()
conn.close()
return result
如果重要的话,执行 Python 代码的 C# 代码如下所示:
using (Process process = Process.Start(start) ?? throw new InvalidOperationException("Process failed to start"))
{
output = process.StandardOutput.ReadToEnd() ?? string.Empty;
error = process.StandardError.ReadToEnd() ?? string.Empty;
process.WaitForExit();
}
我遇到的具体问题是:Python 执行完成后不久,C# 代码会执行少量其他操作,然后尝试更改数据库上执行请求的两个值。具体来说,它按 ID 获取执行请求,将状态更改为“完成”,将进度更改为 100(如 100%),然后将对象保存到数据库。问题是,我的执行请求最终是“完成”,但进度 = 99。换句话说,Python 代码的最终 SQL 调用在 Python 代码完成运行之后以及 C# 运行完成之后完成。代码已经执行了几行代码,甚至写入了同一个数据库表本身。 这怎么可能? 我可以通过将
time.sleep(5)
放在
return
中的
my_function
之前来解决这个问题,但这感觉就像是一个愚蠢的创可贴修复。难道cursor.commit()不应该在Python表明一切都完成之前就完成执行吗?cursor.commit()
while
循环,在看到它完成之前什么也不做(只需在那里等待 0 秒以避免崩溃)