簡體   English   中英

Python 通過 win32com 運行 MessageQueue.Peek,如何獲得超時?

[英]Python running MessageQueue.Peek via win32com, how to get timeout right?

對於初學者,我想說如果有人可以在這里提供幫助,你真是太不可思議了。

一般問題

我的 Python 程序需要與 MSMQ 交互。 基本上,我想查看隊列,如果隊列中沒有任何內容,則指定超時。

但是,盡管我盡了最大努力,但當隊列中沒有任何值時,我無法讓 Peek() 等待超時間隔。 你能指出這段代碼中缺少什么嗎?


我當前的代碼

這是我現在的代碼:

from socket import gethostname

import win32com.client
import pythoncom

import clr
clr.AddReference("System")
clr.AddReference("System.Messaging")
from System import TimeSpan
from System.Messaging import MessageQueue


# Source: [1]
# [1] https://docs.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms707027%28v%3dvs.85%29
MQ_DENY_NONE = 0x0
MQ_PEEK_ACCESS = 0x1
MQ_SEND_ACCESS = 0x2


# Set up queue
pythoncom.CoInitialize()
qinfo = win32com.client.Dispatch("MSMQ.MSMQQueueInfo")
qinfo.FormatName = f"direct=os:{gethostname()}\\PRIVATE$\\MyQueue"
queue = qinfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)

# Receive a value
timeout_sec = 1.0
timespan = TimeSpan.FromSeconds(timeout_sec)
label, body = "", ""
# TODO: timeout value does not appear working. It never waits when
#  there's no message
if queue.Peek(pythoncom.Empty, pythoncom.Empty, timespan):
    msg = queue.Receive() . # Blocking receive --> remove msg from the queue
    if msg is not None:
        label = msg.Label
        body = msg.Body

我運行: inspect.getfullargspec(queue.Peek)並得到:

FullArgSpec(args=['self', 'WantDestinationQueue', 'WantBody', 'ReceiveTimeout', 'WantConnectorType'], varargs=None, varkw=None, defaults=(<PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>), kwonlyargs=[], kwonlydefaults=None, annotations={})

我嘗試過的事情

這個問題:說ReceiveTimeout=timespan似乎並不能解決我的問題。

pythoncom.Missing替換pythoncom.Empty似乎不起作用

這個未回答的問題似乎與我的非常相似

我發現這篇文章正在發送-msmq-messages-python

本文向您展示了如何使用 msmq 發送和接收消息。 我不明白為什么你不能只用標准套接字連接語法說如果我沒有收到數據包/連接然后關閉連接

import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

所以這樣的事情應該不會太難。 最壞的情況是創建一個線程檢查每個 timeout_time 變量是否為零。 如果它是零關閉隊列,如果它 >0 設置為零並等待更多消息,則沒有收到任何消息。 我還發現了一個關於用於 python 日志記錄的異步 msmq 的 GitHub。 異步msmq這個剛剛說receive while True dlopes7 msmq

import time
t_end = time.time() + 60 * 15
messages=0
while time.time() < t_end or messages>0:
    msg = queue.Receive()
    messages+=1
    if(time.time() > t_end and messages>0):
        messages=0
        t_end = time.time() + 60 * 15
    print(f'Got Message from {queue_name}: {msg.Label} - {msg.Body}')

不是您想要的答案,而是可行的答案。

在原始問題的評論中,@PeterBrittain 建議嘗試僅使用:

超時的 integer(以毫秒為單位)

我開始嘗試這個,實際上,它奏效了! 我發現float值也可以工作。 這是一些示例 Python 代碼:

timeout_sec = 1.0
queue.Peek(pythoncom.Empty, pythoncom.Empty, timeout_sec * 1000):

謝謝@PeterBrittain!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM