我正在爲Windows窗體編寫大量單元測試,並且至今已經能夠弄清楚如何設置私有控件的屬性並調用其方法,反射。但我堅持如何將內聯lambda關聯到其中一個控件上發生的事件,在這種情況下是DataGridView的DataSourceChanged事件。我如何將匿名操作綁定爲使用反射的新事件處理程序
public static void ObserveGrid(this Form form, string controlName, Action action)
{
var controls = form.Controls.Find(controlName, true);
if (controls.Any())
{
var control = controls[0] as DataGridView;
if (control != null)
{
EventInfo ei = typeof(DataGridView).GetEvent("DataSourceChanged");
if (ei != null)
{
ei.AddEventHandler(control, Delegate.CreateDelegate(ei.EventHandlerType, control, action.Method));
}
}
}
}
我希望能這樣稱呼它:
var monitor = new Mutex();
form.ObserveGrid("dataGridView1",
() =>
{
Trace.WriteLine("Releasing mutex.");
monitor.ReleaseMutex();
});
var sw = new Stopwatch();
form.ClickButton("btnSearch", sw);
monitor.WaitOne();
sw.Stop();
在執行過程中,我得到了一個錯誤:
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
我是什麼在這種情況下做錯了什麼?
UPDATE:
使用this偉大的職位,我已經改變了我的擴展類,像這樣:
public static void ObserveGrid(this Form form, string controlName, Action<object,object> action)
{
var controls = form.Controls.Find(controlName, true);
if (controls.Any())
{
var control = controls[0] as DataGridView;
if (control != null)
{
EventInfo ei = typeof(DataGridView).GetEvent("DataSourceChanged");
if (ei != null)
{
Delegate handler = ConvertDelegate(action, ei.EventHandlerType);
ei.AddEventHandler(control, handler);
}
}
}
}
public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType)
{
return Delegate.CreateDelegate(
targetDelegateType,
originalDelegate.Target,
originalDelegate.Method);
}
但是我得到的另一個錯誤,這一次有關從非同步釋放互斥螺紋:
Releasing mutex. System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. ----> System.ApplicationException : Object synchronization method was called from an unsynchronized block of code.
更新2
爲SemaphoreSlim交換互斥鎖解決了同步問題。