2009-04-21 16 views
15

मैं माउस कर्सर की वर्तमान स्थिति की निगरानी करने के लिए एक हुक बनाने की कोशिश कर रहा हूं। कुछ भी महत्वपूर्ण नहीं है, मुझे इंटरफ़ेस डिज़ाइन के दौरान कुछ पिक्सेल गिनने की आवश्यकता है और सीखना चाहता था कि कैसे एक हुक बनाना है, इसलिए मैंने एक सैनी तरीके के बजाय कठिन तरीके से जाने का फैसला किया।AppDomain.GetCurrentThreadID बनाम Thread.ManagedThreadID विंडोज एपीआई कॉल के लिए?

मैंने पाया उदाहरण कोड है जो निम्न समारोह वाणी:

<DllImport("User32.dll", CharSet:=CharSet.Auto, _ 
CallingConvention:=CallingConvention.StdCall)> _ 
Public Overloads Shared Function SetWindowsHookEx _ 
     (ByVal idHook As Integer, ByVal HookProc As CallBack, _ 
     ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer 
End Function 

जब समारोह कहा जाता है, निम्नलिखित कोड प्रयोग किया जाता है:

 hHook = SetWindowsHookEx(WH_MOUSE, _ 
           hookproc, _ 
           IntPtr.Zero, _ 
           AppDomain.GetCurrentThreadId()) 

लेकिन Appdomain.GetCurrentThreadID चेतावनी उत्पन्न करता है: "'सार्वजनिक साझा फ़ंक्शन GetCurrentThreadId() इंटेगर के रूप में अप्रचलित है:' AppDomain.GetCurrentThreadId को बहिष्कृत कर दिया गया है क्योंकि यह स्थिर आईडी प्रदान नहीं करता है जब प्रबंधित थ्रेड फाइबर (उर्फ हल्के धागे) पर चल रहे होते हैं। प्रबंधित के लिए स्थिर पहचानकर्ता प्राप्त करने के लिए वें पढ़ें, थ्रेड पर प्रबंधित थ्रेड आईडी संपत्ति का उपयोग करें। "

मैंने प्रबंधित थ्रेड आईडी का उपयोग करने का प्रयास किया है, लेकिन यह काम नहीं करता है। लौटाई गई थ्रेड आईडी थ्रेड की लॉजिकल थ्रेड आईडी प्रतीत होती है, क्योंकि यह Win32 थ्रेड पहचानकर्ता के बजाय .NET रनटाइम में चलता है।

फ़ंक्शन को कॉल करना AppDomain.GetCurrentThreadID काम करता है, लेकिन मैं वास्तव में अपने धागे के लिए "स्थिर पहचानकर्ता" रखना चाहता हूं।

क्या कोई मुझे बता सकता है कि इस संदर्भ में मैनेज्ड थ्रेड आईडी का उपयोग करना संभव है (मुझे नहीं लगता) और यदि नहीं, तो मुझे AppDomain.CurrentThreadID को "अस्थिर" बनने से रोकने के लिए उन चीजों से बचने की आवश्यकता है?

चीयर्स

+0

इस मुद्दे के लिए आप एक समाधान खोजने में सक्षम थे या नहीं? – amadib

+0

वास्तव में नहीं, नहीं। मैं मूल रूप से इसके लिए जेरेडपार का शब्द लेता हूं कि थ्रेडआईडी उचित रूप से स्थिर होगा, परीक्षण के दौरान इसका इस्तेमाल किया जाता था, और फिर अंतिम तैनाती के लिए ऑनमोउसमोव घटनाओं पर प्रतिक्रिया करने के लिए इंटरफेस बदल दिया। मैंने मूल रूप से ऐसा नहीं किया क्योंकि इसका मतलब नियंत्रण की पूरी श्रृंखला के माध्यम से घटनाओं को पार करना है और आमतौर पर गधे में दर्द होता है। हालांकि, यह उपरोक्त विधि से अधिक विश्वसनीय है, जो पूरे परीक्षण के दौरान केवल एक या दो बार विफल रहा, लेकिन असफल रहा। – Frosty840

उत्तर

13

यह संभव नहीं है कि इस संदर्भ में ManagedThreadId उपयोग करने के लिए। यह एक पूरी तरह से प्रबंधित अवधारणा है और मूल दुनिया में इसका कोई वास्तविक प्रतिनिधित्व नहीं है। इसलिए यह एपीआई के लिए कोई समझ नहीं आता है कि आप इसे पास कर रहे हैं।

कारण प्रबंधित थ्रेड आईडी मौजूद है क्योंकि मूल और प्रबंधित धागे के बीच 1-1 मैपिंग आवश्यक नहीं है। सीएलआर एक देशी प्रबंधित धागे को चलाने के लिए कई देशी धागे का उपयोग करने के लिए स्वतंत्र है जब तक कि मूल धागा उस स्थान के साथ संगत न हो। उदाहरण के लिए, यह एक अलग COM अपार्टमेंट में नहीं हो सकता है।

कुछ तरीकों से आप यहां थोड़ा फंस गए हैं। AFAIK, 100% गारंटी का कोई तरीका नहीं है कि आपके पास दिए गए प्रबंधित थ्रेड के लिए एक ही मूल धागा होगा। आप बहुत उच्च स्तर की गारंटी प्राप्त कर सकते हैं, हालांकि यदि आप उदाहरण के लिए WinForms या WPF अनुप्रयोग चला रहे हैं और यूआई थ्रेड पर देशी कोड पर कॉल होता है। कारण यह है कि इन दोनों यूआई ढांचे एसटीए अपार्टमेंट में रहते हैं जो सीएलआर के लिए आप से बाहर निकलने के लिए बहुत कठिन (यदि संभव हो) बनाता है।

लघु संस्करण: यदि आप WinForms या WPF एप्लिकेशन में हैं और UI थ्रेड पर इसे चला रहे हैं, तो आप इस पहचानकर्ता के लिए स्थिरता का उचित स्तर मान सकते हैं।

3

भविष्य के पाठकों के लिए: सिस्टम भी हैं। थ्रेडिंग। थ्रेड। बेगिन थ्रेड अफ़िनिटी()/एंड थ्रेड एफ़िनिटी() फ़ंक्शन जो VM को अलग-अलग भौतिक धागे के बीच स्विच करने से रोकते हैं। मुझे इन गारंटी स्थिरता पर विश्वास नहीं है, लेकिन मुझे लगता है कि वे स्थिर होने की अधिक संभावना रखते हैं।

3

आप इस्तेमाल कर सकते हैं:

using System.Diagnostics; 
Process.GetCurrentProcess().Threads[0].Id 
बजाय

AppDomain.GetCurrentThreadId()

समस्या केवल धागा की सही संख्या पता लगाने के लिए किया जाता है अगर आप की तुलना में मुख्य थ्रेड 0 चल अधिक धागे है ।

3
var thread = Process.GetCurrentProcess().Threads.OfType<ProcessThread>(). 
    SingleOrDefault(x => x.ThreadState == ThreadState.Running); 

if (thread != null) 
{ 
    // do stuff here 
} 
+0

यह एक काफी मानक विंडोज फॉर्म प्रोग्राम में काम करता है। यह वही थ्रेड आईडी को AppDomain.GetCurrentThreadId() के रूप में देता है। यकीन नहीं है कि अगर यह फाइबर पर सही तरीके से काम करता है जैसे AppDomain.GetCurrentThreadId के बारे में चेतावनी देता है –

0

उपयोग:

[DllImport ("kernel32.dll")] GetCurrentThreadId uint स्थिर निर्वासन();

संबंधित मुद्दे