在此回应,我想出了可能由不同的可重复使用下面的辅助方法Task
创作者的事件到任务完成转换的来源。
// Helper method
static Task<T> TaskFromEventHelper<T>(object target, string eventName, Func<TaskCompletionSource<T>, object> resultSetterFactory) {
var tcs = new TaskCompletionSource<T>();
var addMethod = target.GetType().GetEvent(eventName).GetAddMethod();
var delegateType = addMethod.GetParameters()[0].ParameterType;
var d = Delegate.CreateDelegate(delegateType, resultSetterFactory(tcs), "Invoke");
addMethod.Invoke(target, new object[] {d});
return tcs.Task;
}
// Empty events (Action style)
static Task TaskFromEvent(object target, string eventName) {
return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource<object>, object>)(tcs => (Action)(() => tcs.SetResult(null))));
}
// One-value events (Action<T> style)
static Task<T> TaskFromEvent<T>(object target, string eventName) {
return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource<T>, object>)(tcs => (Action<T>)(tcs.SetResult)));
}
// Two-value events (Action<T1, T2> or EventHandler style)
static Task<Tuple<T1, T2>> TaskFromEvent<T1, T2>(object target, string eventName) {
return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource<Tuple<T1, T2>>, object>)(tcs => (Action<T1, T2>)((t1, t2) => tcs.SetResult(Tuple.Create(t1, t2)))));
}
在每三个例子我给使用辅助方法,有一个tcs.SetResult
组件,它让我觉得有一种方法来移动到helper方法也是如此,这可能也许是简化签名,所以,也许helper方法将不得不接受一个Func<?, T>
这里是Func
将采取的输出event
,并将其转换到任何tcs.SetResult
需要。
即,我想必须有一个方法来创建一个帮手,所以我可以把它写成
// Empty events (Action style)
static Task TaskFromEvent(object target, string eventName) {
return TaskFromEventHelper<object>(target, eventName, new Func<object>(() => null));
}
// One-value events (Action<T> style)
static Task<T> TaskFromEvent<T>(object target, string eventName) {
return TaskFromEventHelper<T>(target, eventName, new Func<T, T>(t => t));
}
// Two-value events (Action<T1, T2> or EventHandler style)
static Task<Tuple<T1, T2>> TaskFromEvent<T1, T2>(object target, string eventName) {
return TaskFromEventHelper<Tuple<T1, T2>>(target, eventName, new Func<T1, T2, Tuple<T1, T2>>(Tuple.Create));
}
,但是这就是为什么我不知道?
在Func<?, T>
的上方。 这其中例如需要?
是两个参数。 难道是中传递过来的object
不知何故? 我有一种感觉,它可能是可能的,但即便如此,它需要一些真正的反射魔法。