我已经编写了这些扩展方法,我想将它们压缩成一个,因为它们有效地完成了同样的事情。我遇到的问题是我无法将HtmlElementEventHandler作为EventHandler参数传入。
public static async Task WaitUntilAsync
(this Action action, Action<EventHandler> addHandler,
Action<EventHandler> removeHandler, Predicate<string> pred)
{
var t = new TaskCompletionSource<bool>();
System.EventHandler handler = new System.EventHandler((s, e) =>
{
if (pred((s as MyAsyncWebBrowser).DocumentTitle))
t.SetResult(true);
});
addHandler(handler);
action();
await t.Task;
removeHandler(handler);
}
public static async Task WaitUntilAsync
(this Action action, Action<System.Windows.Forms.HtmlElementEventHandler> addHandler,
Action<System.Windows.Forms.HtmlElementEventHandler> removeHandler, Predicate<string> = h => true)
{
var t = new TaskCompletionSource<bool>();
System.Windows.Forms.HtmlElementEventHandler handler = new System.Windows.Forms.HtmlElementEventHandler((s, e) =>
{
if (pred)
t.TrySetResult(true);
});
addHandler(handler);
action();
await t.Task;
removeHandler(handler);
}
有什么想法吗?
以前的尝试
public static async Task WaitUntilAsync<TDelegate>
(this Action action, Action<TDelegate> addHandler,
Action<TDelegate> removeHandler, Predicate<string> pred)
{
var t = new TaskCompletionSource<bool>();
TDelegate handler = (s, e) =>
{
if (pred((s as MyAsyncWebBrowser).DocumentTitle))
t.SetResult(true);
};
addHandler(handler);
action();
await t.Task;
removeHandler(handler);
}
这使我&#34;无法将Lambda表达式转换为Type Delegate,因为它不是委托类型。&#34;在一开始。
答案 0 :(得分:2)
试试这个作为你的定义。一定要爱仿制药!
public static async Task WaitUntilAsync<T>(this Action action, Action<T> addHandler, Action<T> removeHandler, Predicate<string> pred) where T : class
不幸的是,你不能使用委托作为通用约束,如下所示:
public static async Task WaitUntilAsync<T>(this Action action, Action<T> addHandler, Action<T> removeHandler, Predicate<string> pred) where T : EventHandler
...所以你必须使用反射确认你的类型,然后手动投射。
这是一个完整的例子:
public static async Task WaitUntilAsync<TDelegate>(this Action action, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, Predicate<string> pred) where TDelegate : class
{
var delegateType = typeof(TDelegate);
if (delegateType != typeof(EventHandler) && !delegateType.IsSubclassOf(typeof(EventHandler))) throw new Exception("TDelegate must be EventHandler or a subclass.");
var t = new TaskCompletionSource<bool>();
EventHandler realHandler = (sender, args) =>
{
//do real event work here
};
var handler = Delegate.CreateDelegate(delegateType, realHandler.Method) as TDelegate;
addHandler(handler);
action();
await t.Task;
removeHandler(handler);
}