我正在编写一个扩展方法,但是其中有一部分出现了问题。
我的想法是:创建一个方法,该方法接受一个对象和事件名称,等待事件被触发,然后返回其事件参数。我将使用它来避免每次在代码中执行此类操作时手动创建委托等内容。
注意:代码位于针对Windows8.1和Windows Phone 8.1的PCL中,因此某些反射方法在此处不可用。
目前为止,我已经完成了以下工作:
现在,标准事件一切正常,没有问题。但是当我使用“RoutedEvents”时,会出现异常。我最终尝试使用“TypedEventHandler”类,因为我没有找到其他方法来获取这些事件的正确委托(如所有指针事件)。但是,当我尝试添加处理程序时,会出现“InvalidOperationException”的异常。是否可能在WinRT上也为RoutedEvents创建运行时处理程序,还是不可能?感谢您的帮助!Sergio
我的想法是:创建一个方法,该方法接受一个对象和事件名称,等待事件被触发,然后返回其事件参数。我将使用它来避免每次在代码中执行此类操作时手动创建委托等内容。
注意:代码位于针对Windows8.1和Windows Phone 8.1的PCL中,因此某些反射方法在此处不可用。
目前为止,我已经完成了以下工作:
/// <summary>
/// Waits for an event to be raised and returns its arguments
/// </summary>
/// <typeparam name="Targs">The type of the event args to return</typeparam>
/// <param name="target">The target object that will raise the event</param>
/// <param name="eventName">The name of the event to wait</param>
/// <param name="timeout">The time limit (in millisecond) to wait for the desired event to be raised</param>
public static async Task<Targs> WaitEventAsync<Targs>(this object target, String eventName, int timeout)
where Targs : class
{
// Arguments check
if (target == null) throw new ArgumentNullException("The target object can't be null");
if (eventName == null) throw new ArgumentNullException("The event name can't be null");
if (timeout <= 0) throw new ArgumentOutOfRangeException("The timeout must be greater than 0");
// Get the target event
EventInfo eventInfo = target.GetType().GetRuntimeEvent(eventName);
if (eventInfo == null) throw new ArgumentException(String.Format("The target object doesn't contain the {0} event", eventName));
// Prepare the TaskCompletionSource, the return variable and the right handler
TaskCompletionSource<Targs> tcs = new TaskCompletionSource<Targs>();
Delegate handler;
if (eventInfo.EventHandlerType.Equals(typeof(EventHandler<Targs>)))
{
handler = new EventHandler<Targs>((sender, args) =>
{
tcs.SetResult(args);
});
}
else
{
// PROBLEM: when this line is executed, the AddEventHandler method crashes
handler = new TypedEventHandler<object, Targs>((sender, args) =>
{
tcs.SetResult(args);
});
}
// Add the handler and wait for the event
eventInfo.AddEventHandler(target, handler);
CancellationTokenSource cts = new CancellationTokenSource(timeout);
try
{
// If the event was triggered before the timout expired, return its args
return await tcs.Task.GetWatchedTask(cts);
}
catch (OperationCanceledException)
{
// If the timout expired, just return null
return null;
}
finally
{
// Remove the handler from the target object
eventInfo.RemoveEventHandler(target, handler);
}
}
现在,标准事件一切正常,没有问题。但是当我使用“RoutedEvents”时,会出现异常。我最终尝试使用“TypedEventHandler”类,因为我没有找到其他方法来获取这些事件的正确委托(如所有指针事件)。但是,当我尝试添加处理程序时,会出现“InvalidOperationException”的异常。是否可能在WinRT上也为RoutedEvents创建运行时处理程序,还是不可能?感谢您的帮助!Sergio