我正在爲多線程應用程序編寫單元測試,其中需要等待特定事件觸發,以便我知道異步操作已完成。例如,當我打電話給repository.add(something)
時,我在做任何斷言之前等待事件AfterChange。所以我寫了一個實用函數來做到這一點:如何在C#中傳遞事件作爲參數
public static void SyncAction(EventHandler event_, Action action_)
{
var signal = new object();
EventHandler callback = null;
callback = new EventHandler((s, e) =>
{
lock (signal)
{
Monitor.Pulse(signal);
}
event_ -= callback;
});
event_ += callback;
lock (signal)
{
action_();
Assert.IsTrue(Monitor.Wait(signal, 10000));
}
}
但是,編譯器阻止將事件傳遞出類。有沒有辦法實現這一點?
下面是使用反射的解決方案。
public static void SyncAction(object target_, string event_, Action action_)
{
SyncAction(
new List<Pair<object, string>>() { new Pair<object, string>(target_, event_) },
action_);
}
public static void SyncAction(IEnumerable<Pair<object, string>> events_, Action action_)
{
var events = events_
.Select(a => new Pair<object, EventInfo>(a.First, a.First.GetType().GetEvent(a.Second)))
.Where(a => a.Second != null);
var count = events.Count();
var signal = new object();
var callback = new EventHandler((s, e) =>
{
lock (signal)
{
--count;
Monitor.Pulse(signal);
}
});
events.ForEach(a => a.Second.AddEventHandler(a.First, callback));
lock (signal)
{
action_();
while (count > 0)
{
Assert.IsTrue(Monitor.Wait(signal, 10000));
}
}
events.ForEach(a => a.Second.RemoveEventHandler(a.First, callback));
}
上午第二次的做法,並會嘗試上的反射。 Rx尚未獲得我公司的批准,但我無法等待。但使用Rx編寫測試用例肯定會容易得多。 – 2010-05-18 14:20:11