首页 > 解决方案 > python:超时后如何在单独的线程中终止Excel会话?

问题描述

我正在 python 中执行 Excel 宏,并希望在超时后将其终止。但是,现有的超时和终止 Excel 处理方法对我不起作用。你能帮忙吗?

import threading
import win32com.client as win;
import pythoncom;

Excel = None;
workbook = None;

def worker(e):
    global Excel;
    global workbook;

    pythoncom.CoInitialize();    
    Excel = win.DispatchEx('Excel.Application');
    Excel.DisplayAlerts = False;
    Excel.Visible = True;
    workbook = Excel.Workbooks.Open("sample.xlsm", ReadOnly = True);
    Excel.Calculation = -4135;
    print "Run";
    Excel.Run('Module2.Refresh');

e = threading.Event()
t = threading.Thread(target=worker, args=(e,));
t.start()

# wait 5 seconds for the thread to finish its work
t.join(5)
if t.is_alive():
    print "thread is not done, setting event to kill thread."
    e.set();
    print "1";
    workbook.Close();
    print "2";
    Excel.Quit();
else:
    print "thread has already finished."
    workbook.Close();
    Excel.Quit();

我收到错误:

Run
thread is not done, setting event to kill thread.
1
Traceback (most recent call last):
  File "check_odbc.py", line 62, in <module>
    workbook.Close();
  File "C:\Users\honwang\AppData\Local\conda\conda\envs\py27_32\lib\site-package
s\win32com\client\dynamic.py", line 527, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: Open.Close

标签: pythonpywin32

解决方案


不幸的是,不可能杀死线程。你所能做的就是很好地要求他们自杀,然后抱最好的希望。仅仅传递一个事件对象是不够的,你必须在线程内主动检查该事件并在设置时自杀。由于您的线程在运行 excel 代码时被阻塞,它无法检查事件 - 这意味着您可以随心所欲地对它大喊大叫,但没有代码让它听。

如果您在固有阻塞代码上需要这种并行性,我强烈建议您改用进程,因为这些可以被杀死。否则,如果可能,请使用异步编程。


推荐阅读