我正在编写一个使用线程的类库,我想把线程安全放到库中,而不是让我们代码的开发人员必须自己实现线程安全。
我有一个活动
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.Target
投射到System.Windows.Forms.Control
,而System.Windows.Forms.Control
没有formType
作为代码中的指定演员,我希望{{1}}完成{{1}} 1}}如果可能的话,我不会被迫自己链接到表单程序集,因为它不是库的要求而不应该是。
或者,是否有更好的方法来做我想做的事情?
答案 0 :(得分: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();
}
}
GetMethod
和GetProperty
方法可能需要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();
}
}
答案 1 :(得分:0)
使用界面ISynchronizeInvoke
。它在System
中,由System.Windows.Forms.Control
实现。