// Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource(); var resultSetter = (Action)(() => tcs.SetResult(null)); var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; } // One-value events (Action style) static Task TaskFromEvent(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource(); var resultSetter = (Action)tcs.SetResult; var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; } // Two-value events (Action or EventHandler style) static Task> TaskFromEvent(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource>(); var resultSetter = (Action)((t1, t2) => tcs.SetResult(Tuple.Create(t1, t2))); var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; }