2011-08-04 4 views
7

'un uygulanması hakkında meraklıdır. Control.Invoke (Delegate), temsilci GUI iş parçacığı üzerinde çalıştırmak için tam olarak ne yapar? Üstelik, onun benimsediği anlayışı, çağrılan işlev gerçekleşene kadar engellenecektir. Bunu nasıl başardı?Control.Invoke()

Bazı iyi cesur detaylar istiyorum. İlginç bir şey öğrenmeyi umuyordum.

+0

[Bu] [1] çıkışını kontrol edin. [1]: http://stackoverflow.com/questions/4514273/does-control-invoke-pump-messages – n8wrl

cevap

4

Düzenleme: Denetim, ISynchronizeInvoke arabirimini uygular, SynchronizationContext'u kullanarak aynı efekti yapabilir ve Invoke'u aradığınızda Post'u arayabilirsiniz. gibi bir şey:

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; 
} 
yansıtıcı kullanarak Invoke bazı yerli API Bunu başarmak için çağırır tarafından kullanıldığını göstermektedir

fazla araştırma: Ben iç görün bilmek istiyorsanız

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

, genellikle ILSpy çalıştırıp bakmak BCL'nin decompiled kaynakları. Alternatif olarak, Mono veya Rotor kaynaklarını indirebilirsiniz.

+2

Veya yansıtıcı kullanın; kötü "R" kelime bile etmeyin) – Abel

+0

! ;-) –

+0

Reflektörün lisansı değiştiyse, Telerik'in dekomplatörünü kullanmaya başladım ve beğendim: http://www.keepdecompilingfree.com – Jamey