2013-09-24 51 views
13

我有一个Python脚本处理来自.NET Remoting的异步回调。这些回调在虚拟(工作者)线程中执行。从我的回调处理程序中,我需要调用我在脚本中定义的函数,但是我需要在主线程中执行该函数。在主线程从虚拟线程调用中执行Python函数

主线程是将命令发送到服务器的远程客户端。其中一些命令会导致异步回调。

基本上,我需要.NET的Invoke方法的等价物。这可能吗?

+0

什么主线程呢?你需要以某种方式发信号并让它调用该函数。如果主线程一般等待事件发生,然后发信号。如果主线程执行处理,则将函数调用到队列中,让主线程偶尔检查和处理队列。 – Claudiu

+0

增加了信息发布。 –

+0

嗯...思考更多....如果回调发生,而主要是等待服务器从通话返回控制,没有办法让主要做任何事情,是吗? –

回答

18

你想使用​​类来建立一个队列,你的虚拟线程用函数填充,并且你的主线程使用它。

import Queue 

#somewhere accessible to both: 
callback_queue = Queue.Queue() 

def from_dummy_thread(func_to_call_from_main_thread): 
    callback_queue.put(func_to_call_from_main_thread) 

def from_main_thread_blocking(): 
    callback = callback_queue.get() #blocks until an item is available 
    callback() 

def from_main_thread_nonblocking(): 
    while True: 
     try: 
      callback = callback_queue.get(False) #doesn't block 
     except Queue.Empty: #raised when queue is empty 
      break 
     callback() 

演示:

import threading 
import time 

def print_num(dummyid, n): 
    print "From %s: %d" % (dummyid, n) 
def dummy_run(dummyid): 
    for i in xrange(5): 
     from_dummy_thread(lambda: print_num(dummyid, i)) 
     time.sleep(0.5) 

threading.Thread(target=dummy_run, args=("a",)).start() 
threading.Thread(target=dummy_run, args=("b",)).start() 

while True: 
    from_main_thread_blocking() 

打印:

From a: 0 
From b: 0 
From a: 1 
From b: 1 
From b: 2 
From a: 2 
From b: 3 
From a: 3 
From b: 4 
From a: 4 

,然后阻止永远

+0

非常酷。 Python使委托传递和存储变得微不足道。我很感谢你非常详细的回答。 –

+0

@JimC:这是为什么它是我最喜欢的语言=)的一部分。干杯 – Claudiu