2013-07-03 44 views
1

我正在編寫一個使用線程的類庫,它的使用非常繁重,我想將線程安全帶入庫中,而不是讓開發人員自己實現線程安全。使用線程安全事件調用反射的盲目鑄造

我有一個事件

public delegate void OnPostHandler(); 
public event OnPostHandler OnPost; 

public void FireEvent() { 
    Delegate[] delegate_list = OnPost.GetInvocationList(); 
    foreach (OnPostHandler d in delegate_list) 
    { 
     //detect if d.Target is a System.Windows.Forms.Control 
     Type formType = Type.GetType("System.Windows.Forms.Control, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 
     if(formType != null) { 
      //need to cast d.Target to System.Windows.Forms.Control WITHOUT referencing System.Windows.Forms.Control 
      if(d.Target.InvokeRequired) { 
       d.Target.Invoke(d); 
      } else { 
       d(); 
      } 
     } else { 
      d(); 
     } 
    } 
} 

FireEvent的方法,我想投d.TargetSystem.Windows.Forms.Control而不System.Windows.Forms.Control被一個指定的代碼內施放,我想如果可能的話,這可以通過formType完成,這樣我就不會被強制鏈接到表單集合本身,因爲它不是圖書館的要求,也不應該是。

另外,有沒有更好的方式做我想做的事情?

回答

1

與反思,您可以:

Delegate[] delegate_list = OnPost.GetInvocationList(); 

Type formType = Type.GetType("System.Windows.Forms.Control, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 
var invokeRequiredProp = formType.GetProperty("InvokeRequired"); 

foreach (OnPostHandler d in delegate_list) 
{ 
    if(formType != null) { 
     var invokeRequired = invokeRequiredProp.GetValue(d.Target, null); 
     if (invokeRequired) { 
      formType.GetMethod("Invoke").Invoke(d.Target, new object[]{d}); 
     } 
     else { 
      d(); 
     } 
    } else { 
     d(); 
    } 
} 

GetMethodGetProperty方法可能需要BindingFlags參數。

沒有反射,你可以使用ISynchronizeInvoke

Delegate[] delegate_list = OnPost.GetInvocationList(); 

foreach (OnPostHandler d in delegate_list) 
{ 
    var form = d.Target as ISynchronizeInvoke; 
    if(form != null && form.InvokeRequired) { 
     form.Invoke(d); 
    } 
    else { 
     d(); 
    } 
} 
0

使用接口ISynchronizeInvoke。它在System中,由System.Windows.Forms.Control執行。