/// <summary> /// Gets a task that will complete the next time an event is raised. The event type must follow the standard <c>void EventHandlerType(object, TResult)</c> pattern. Be mindful of race conditions (i.e., if the event is raised immediately before this method is called, your task may never complete). /// </summary> /// <param name="target">The object that publishes the event. May not be <c>null</c>.</param> /// <param name="eventName">The name of the event. May not be <c>null</c>.</param> /// <returns>The event args.</returns> public static Task <TResult> FromEvent(object target, string eventName) { var eventInfo = ReflectionShim.GetEvent(target.GetType(), eventName); if (eventInfo == null) { throw new InvalidOperationException("Could not find event " + eventName + " on type " + target.GetType().FullName); } return(new EventArgsTask <TResult>(target, eventInfo).Task); }
/// <summary> /// Gets a task that will complete the next time an event is raised. The event type must follow the standard <c>void EventHandlerType(object, TResult)</c> pattern. Be mindful of race conditions (i.e., if the event is raised immediately before this method is called, your task may never complete). /// </summary> /// <param name="target">The object that publishes the event.</param> /// <returns>The event args.</returns> public static Task <TResult> FromEvent(object target) { // Try to look up an event that has the same name as the TResult type (stripping the trailing "EventArgs"). var type = target.GetType(); var resultType = typeof(TResult); var resultName = resultType.Name; if (resultName.EndsWith("EventArgs", StringComparison.Ordinal)) { var eventInfo = ReflectionShim.GetEvent(type, resultName.Remove(resultName.Length - 9)); if (eventInfo != null) { return(new EventArgsTask <TResult>(target, eventInfo).Task); } } // Try to match to any event with the correct signature. EventInfo match = null; foreach (var eventInfo in ReflectionShim.GetEvents(type)) { var invoke = ReflectionShim.GetMethod(eventInfo.EventHandlerType, "Invoke"); if (invoke.ReturnType != typeof(void)) { continue; } var parameters = invoke.GetParameters(); if (parameters.Length != 2 || parameters[0].ParameterType != typeof(object) || parameters[1].ParameterType != resultType) { continue; } if (match != null) { throw new InvalidOperationException("Found multiple matching events on type " + target.GetType().FullName); } match = eventInfo; } if (match == null) { throw new InvalidOperationException("Could not find a matching event on type " + target.GetType().FullName); } return(new EventArgsTask <TResult>(target, match).Task); }