7

这是对https://stackoverflow.com/questions/37684111/ironpython-exe-file-closing-immediately-no-exception-throw的跟进

我发现由于线程库中的 Timer 对象存在问题,我的程序一旦编译就无法工作。我已将该库包含在我的 \Lib\site-packages 目录中,并将该目录添加到程序的路径中。这是我正在使用的测试代码 - 一个简单的计数程序:

import sys
from threading import Timer

sys.path.append('C:\Users\[user]\Documents\Visual Studio 2015\Projects\Testing Timer Compilation issue\Testing Timer Compilation issue')
sys.path.append('C:\Users\[user]\Documents\Visual Studio 2015\Projects\Testing Timer Compilation issue\Testing Timer Compilation issue\Lib')

class Chron():
    def __init__(self):
        self.t = Timer(2, self.count)
        self.t.start()
        self.i = 0

    def count(self):
        print(self.i)
        self.i += 1
        if self.i <= 15:
            self.t = Timer(2, self.count)
            self.t.start()

c = Chron()

在 Visual Studio 的交互式解释器中完美运行,但是一旦我使用 pyc.py 编译为 exe 文件,它就不会运行,并且会在大约 5 秒后关闭,不会抛出异常。

如上一个问题所述,我有一个需要编译的带有 Timer 的程序,因为源代码包含敏感凭据。是否有任何技巧可以使 Timer 在 exe 中工作?它只是不兼容吗?

编辑:6天没有答案。不幸的是,互联网上的任何地方似乎都没有针对此特定问题的任何资源。就好像我是唯一一个有这个问题的人。这对我来说似乎很奇怪,因为问题似乎出在 Timer 对象本身,而且我无法想象没有其他人试图部署一个包含 Timer 的应用程序。在这一点上,任何见解都会有所帮助,因为我完全被难住了。

4

1 回答 1

5

问题是您依赖底层 Python 解释器来优雅地处理可执行文件的主线程已终止的情况,但应该还有其他一些仍在运行。

直接使用 CPython 或 IronPython 运行代码可以按预期工作。您创建的 Timer 对象实际上是 Thread 的特化。解释器识别出一些非守护线程仍然处于活动状态,因此不会终止。如果您不知道这两种类型的线程之间的区别,请参阅文档以获取对守护线程的解释。

但是,当您作为可执行文件运行时,IronPython 用来包装解释器的代码似乎不是那么好。它只是等待主线程结束,然后关闭所有内容。尽管您的计时器被声明为非守护线程,但仍会发生这种情况。可以说这是 IronPython 中的一个错误。

因此,解决方案是让您的主线程运行,而您的 Timer 线程仍在运行。对于此示例代码,最简单的方法就是休眠 - 例如:

import sys
sys.path.append(r"c:\Program Files (x86)\IronPython 2.7\Lib")
from threading import Timer
from time import sleep

class Chron():
    def __init__(self):
        self.t = Timer(2, self.count)
        self.t.start()
        self.i = 0

    def count(self):
        print(self.i)
        self.i += 1
        if self.i <= 15:
            self.t = Timer(2, self.count)
            self.t.start()

c = Chron()
sleep(35)

但是,对于更复杂的应用程序,您应该考虑线程之间的一些通信以协调何时关闭 - 例如使用join()等待线程终止。

于 2016-07-07T17:06:30.770 回答