1

Say I want to execute two sections of code each 3 seconds and 0.1 second at the same time. How should I do that?

I will use a VBScript as an example:

Sub ScriptStart
    View.SetTimerInterval1(3000)
    View.SetTimerInterval2(100)
    View.EnableTimer1(True)
    View.EnableTimer2(True)
End Sub

Sub ScriptStop
    View.EnableTimer1(False)
    View.EnableTimer2(False)

Sub OnScriptTimer1
    dosomething
End Sub

Sub OnScriptTimer2
    dosomethingelse
End Sub

The code should let two on script timers execute do_something and do_something_else every 3 seconds and 0.1 second. How can I do it in Python? I used time.sleep() and while True loop to set the timer interval, but how do I implement two timers at the same time? I tried to use thread in Python:

def OnProjectRun:
    t1 = threading.Thread(target=OnScriptTimer1)  
    t2 = threading.Thread(target=OnScriptTimer2) 
    t1.start()
    t2.start()

def OnScriptTimer1:
    dosomething()

def OnScriptTimer2:
    dosomethingelse()

def dosomething:
    #acutual code

def dosomethingelse:
    #actual code

Then I get the error:

Traceback (most recent call last):
  File "C:\Python25\Lib\threading.py", line 486, in __bootstrap_inner
    self.run()
  File "C:\Python25\Lib\threading.py", line 446, in run
    self.__target(*self.__args, **self.__kwargs)
  File "PyEditView1", line 314, in OnScriptTimer2
  File "PyEditView1", line 230, in Get_FieldValue
  File "C:\Python25\lib\site-packages\win32com\client\__init__.py", line 463, in __getattr__
    return self._ApplyTypes_(*args)
  File "C:\Python25\lib\site-packages\win32com\client\__init__.py", line 456, in _ApplyTypes_
    self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),
com_error: (-2147417842, 'The application called an interface that was marshalled for a different thread.', None, None)

In this case, Get_FieldValue is dosomethingelse.

  • 1
    your problem may have nothing to do with code which you show but with code which you have in `dosomething()`, and `dosomethingelse()` - so show full error - Traceback - not only last line of message. – furas Aug 19 '19 at 14:25
  • Have updated. Thank you for the notice. – Ziyang Shen Aug 19 '19 at 18:21

2 Answers2

2

Looking at the error message, you are using pywin32 in the code you are not showing us. Apparently you are using COM objects.

According to this answer:

On Windows, COM objects are protected the same sort of way. If you create an COM object on a thread it doesn't like you trying to access it on a different thread.

So, you probably created some COM object in one thread and are then trying to use it in another thread. Windows doesn't like that, hence the error.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
1

Check out Python's scheduler module; sched. I think you can adapt it to meet your needs.Here is an example to get you started;

import sched, time
s = sched.scheduler(time.time, time.sleep)

def on_script_timer1():
    print("Timer1")
    s.enter(3, 1, on_script_timer1)
    s.run()

def main():
    print(time.time())
    s.enter(3, 1, on_script_timer1)
    s.run()

if __name__ == '__main__':
    main()

1566225979.83796
Timer1
Timer1
Timer1
Timer1


You could also use a Timer; tutorial

import threading 
def mytimer(): 
   print("Python Program\n") 
my_timer = threading.Timer(3.0, mytimer) 
my_timer.start() 
print("Bye\n") 
SteveJ
  • 3,034
  • 2
  • 27
  • 47