पायथन चल रहा है MessageQueue.Peek win32com के माध्यम से, कैसे टाइमआउट सही पाने के लिए?


9

शुरुआत के लिए, मैं कहना चाहूंगा कि अगर कोई यहां मदद कर सकता है, तो आप अविश्वसनीय हैं।

सामान्य प्रश्न

मेरे पायथन कार्यक्रम को MSMQ के साथ बातचीत करने की आवश्यकता है। मूल रूप से, मैं एक कतार में झांकना चाहता हूं, यदि कोई कतार में कुछ भी नहीं है तो टाइमआउट निर्दिष्ट करना।

हालांकि, मेरे सर्वोत्तम प्रयासों के बावजूद, मैं पीक () को टाइमआउट अंतराल की प्रतीक्षा नहीं कर सकता, जब कतार में पहले से कोई मूल्य नहीं है। क्या आप कृपया बता सकते हैं कि इस कोड से क्या गायब है?


मेरा वर्तमान कोड

यहाँ मेरा कोड अभी है:

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.Emptyसाथ प्रतिस्थापित pythoncom.Missingकरने के लिए काम नहीं लगता है

यह अनुत्तरित प्रश्न मेरे लिए बहुत समान लगता है


pythoncom है CoWaitForMultipleHandles(Flags, Timeout , Handles )क्या यह आपकी मदद करता है?
8

हाय @LinPy आप विस्तृत मन? यह मदद कर सकता है, यह एक समाधान की तरह लगता है, हालांकि। मैं सोच रहा हूं कि टाइमआउट के लिए सही तरीके से queue.Peek
आर्गन्स

1
बस एक विचार है, लेकिन अन्य उदाहरण मैंने पायथन में इस इंटरफ़ेस के बारे में देखा है, बस अपने पूर्ण समय के लिए एक पूर्णांक (मिलीसेकंड में) का उपयोग करते हैं। हो सकता है कि pywin32 आपके द्वारा अपेक्षित समय TimeSpans को हैंडल नहीं कर रहा हो ...
पीटर ब्रिटैन

@PeterBrittain आपको धन्यवाद, कि वास्तव में यह चाल चली गई! मैंने नीचे दिए गए जवाब के रूप में आपकी टिप्पणी पोस्ट की।
इंट्रासेलर एक्सप्लोरर

जवाबों:


0

मुझे यह लेख भेजने का पता चला- msmq-messages-python

लेख आपको दिखाता है कि msmq का उपयोग करके एक संदेश कैसे भेजें और प्राप्त करें। मुझे समझ में नहीं आता है कि आप मानक सॉकेट कनेक्शन सिंटैक्स को यह कहने के लिए क्यों नहीं कह सकते हैं कि अगर मुझे पैकेट / कनेक्शन नहीं मिला है तो कनेक्शन बंद करें

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

तो ऐसा कुछ मुश्किल नहीं होना चाहिए। सबसे खराब स्थिति परिदृश्य एक थ्रेड बनाता है जो प्रत्येक टाइमआउट_टाइम की जांच करता है कि कोई चर शून्य है या नहीं। यदि यह शून्य पास कतार है तो कुछ भी नहीं मिला अगर यह 0 पर सेट हो तो और अधिक संदेशों की प्रतीक्षा करें। मैं भी अजगर लॉगिंग के लिए अतुल्यकालिक msmq के बारे में एक GitHub पाया। अतुल्यकालिक msmq यह सिर्फ सच 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}')

जवाब नहीं जो आप चाहते थे, लेकिन एक काम करेगा।


नमस्कार @MichaelHearn! कई उपयोगी वर्कअराउंड प्रदान करने के लिए धन्यवाद। जैसे, मैं आपको इनाम :)
Intrastellar Explorer

धन्यवाद! @IntrastellarExplorer
माइकल हर्न

0

मूल प्रश्न की टिप्पणियों में, @PeterBrittain ने केवल उपयोग करने का प्रयास करने का सुझाव दिया:

उनके समय के लिए एक पूर्णांक (मिलीसेकंड में)

मैं बाहर की कोशिश कर रहा है, और वास्तव में, यह काम किया! मुझे floatकाम करने के लिए मान मिला । यहाँ कुछ नमूना पायथन कोड है:

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

धन्यवाद @PeterBrittain!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.