2011-08-04 3 views
7

के कार्यान्वयन के बारे में उत्सुकता GUI थ्रेड पर चलाने के लिए प्रतिनिधि को प्राप्त करने के लिए नियंत्रण। इन्वोक (प्रतिनिधि) क्या करता है? इसके अलावा, यह मेरी समझ है कि आह्वान समारोह तब तक अवरुद्ध होगा जब तक कि इसे लागू किए गए कार्य को पूरा नहीं किया जाता है। यह कैसे प्राप्त करता है?Control.Invoke()

मुझे कुछ अच्छे किरकिरा विवरण चाहिए। मैं कुछ दिलचस्प सीखने की उम्मीद कर रहा हूँ।

+0

[यह] [1] बाहर की जाँच करें। [1]: http://stackoverflow.com/questions/4514273/does-control-invoke-pump-messages – n8wrl

उत्तर

4

संपादित करें: नियंत्रण लागू करता ISynchronizeInvoke इंटरफेस, आप SynchronizationContext का उपयोग कर एक ही प्रभाव बनाने के लिए और फोन Post जब आप Invoke कॉल कर सकते हैं। कुछ की तरह:

public object Invoke(Delegate method, object[] args) 
{ 
    if (method == null) 
    { 
     throw new ArgumentNullException("method"); 
    } 

    object objectToGet = null; 

    SendOrPostCallback invoker = new SendOrPostCallback(
    delegate(object data) 
    { 
     objectToGet = method.DynamicInvoke(args); 
    }); 

    _currentContext.Send(new SendOrPostCallback(invoker), method.Target); 

    return objectToGet; 
} 

आगे की जांच परावर्तक का उपयोग कर पता चलता Invoke का उपयोग करता है कुछ देशी एपीआई कि प्राप्त करने के लिए कहता है:

private object MarshaledInvoke(Control caller, Delegate method, object[] args, bool synchronous) 
{ 
    int num; 
    if (!this.IsHandleCreated) 
    { 
     throw new InvalidOperationException(SR.GetString("ErrorNoMarshalingThread")); 
    } 
    if (((ActiveXImpl) this.Properties.GetObject(PropActiveXImpl)) != null) 
    { 
     IntSecurity.UnmanagedCode.Demand(); 
    } 
    bool flag = false; 
    if ((SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, this.Handle), out num) == SafeNativeMethods.GetCurrentThreadId()) && synchronous) 
    { 
     flag = true; 
    } 
    ExecutionContext executionContext = null; 
    if (!flag) 
    { 
     executionContext = ExecutionContext.Capture(); 
    } 
    ThreadMethodEntry entry = new ThreadMethodEntry(caller, this, method, args, synchronous, executionContext); 
    lock (this) 
    { 
     if (this.threadCallbackList == null) 
     { 
      this.threadCallbackList = new Queue(); 
     } 
    } 
    lock (this.threadCallbackList) 
    { 
     if (threadCallbackMessage == 0) 
     { 
      threadCallbackMessage = SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion + "_ThreadCallbackMessage"); 
     } 
     this.threadCallbackList.Enqueue(entry); 
    } 
    if (flag) 
    { 
     this.InvokeMarshaledCallbacks(); 
    } 
    else 
    { 
     UnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero); 
    } 
    if (!synchronous) 
    { 
     return entry; 
    } 
    if (!entry.IsCompleted) 
    { 
     this.WaitForWaitHandle(entry.AsyncWaitHandle); 
    } 
    if (entry.exception != null) 
    { 
     throw entry.exception; 
    } 
    return entry.retVal; 
} 
1

मैं आंतरिक जानना चाहते हैं, मैं आमतौर पर अप ILSpy आग और देखो बीसीएल के अपघृत स्रोत। वैकल्पिक रूप से, आप Mono या Rotor स्रोत डाउनलोड कर सकते हैं।

+2

या परावर्तक का उपयोग करें;) – Abel

+0

आप यह नहीं कह बुरा "आर" शब्द क्या! ;-) –

+0

अगर परावर्तक का लाइसेंस बदल गया, तो मैंने टेलीरिक के डिकंपेलर का उपयोग शुरू किया और इस तरह: http://www.keepdecompilingfree.com – Jamey