【发布时间】:2020-03-06 19:30:29
【问题描述】:
我正在使用一个借用的 Python 脚本,该脚本在 main function 之外定义的类中具有两个函数定义(get_data 和 get_data_multiple)。 main 函数调用get_data_multiple,后者又调用get_data。简而言之,我的代码使用 win32com 模块 (from win32com.client.dynamic import Dispatch) 获取 Pi 数据。
目标是每小时运行一次main 函数。我通过使用while True: 循环和来自time 模块的time.time() 来做到这一点。在极少数情况下,我发现调用get_data 需要很长时间才能将返回值发送到get_data_multiple。在这些情况下,我的代码崩溃了,当main 的返回值到达时,它已经过了一个小时。
我想添加一个逻辑,在此我终止对get_data 的调用,并在其中花费的时间超过一定时间时强制它返回默认值。我知道该函数在pi_values = tag.Data.InterpolatedValues2(t_start, t_end, t_interval, asynchStatus=None) 行中花费了太多时间。当我没有可用的函数返回值时,我该怎么做?
def get_data(self, tag_name, t_start, t_end, t_interval):
"""Retrieve interpolated data from the PI-server
Args:
tag_name (str): PI tag name
t_start (str): PI time format (ex. '*-72h')
t_end (str): PI time format (ex. '*')
t_interval (str): PI time format (ex. '1h')
Returns:
pandas dataframe: index=datetime, col_1=interpolated values
"""
logger.info('get_data for tag `%s`' % tag_name)
tag = self.pi_srv.PIPoints(tag_name)
pi_values = tag.Data.InterpolatedValues2(t_start, t_end, t_interval, asynchStatus=None)
return (self.pivalues_to_df(pi_values, tag_name))
def get_data_multiple(self, tags, t_start, t_end, t_interval):
"""Retrieve interpolated data from the PI-server for multiple tags
Args:
tags (list): List of PI tag names
t_start (str): PI time format (ex. '*-72h')
t_end (str): PI time format (ex. '*')
t_interval (str): PI time format (ex. '1h')
Returns:
pandas dataframe: index=datetime, cols=interpolated values
"""
logger.info('getting data for %s tags' % len(tags))
list_of_values = []
pBar = ProgressBar()
for i,tag in enumerate(tags):
print(i)
df = None
while df is None:
try:
df = self.get_data(tag, t_start, t_end, t_interval)
except:
print('Connection Timeout. Retring.....')
pass
# drop duplicated indices -> result of summer-to-winter time
# transition. Not doing this results in the subsequent join() to
# spiral out of control
df = df[~df.index.duplicated()]
list_of_values.append(df)
df_values = pd.DataFrame().join(list_of_values, how='outer')
#print(df_values.columns)
return df_values
【问题讨论】:
-
我认为您可以尝试生成一个新进程并为其设置超时 - 在此处查看其他解决方案 stackoverflow.com/questions/492519/timeout-on-a-function-call
-
产生一个线程。请看this QA