Answered by:
Observable.FromEvent throws in v1.0.10425

Question
-
I'm having trouble using the new Observable.FromEvent with typical WPF events - here's my code:
Observable.FromEvent<SizeChangedEventHandler, SizeChangedEventArgs>( x => SizeChanged += x, x => SizeChanged -= x) .Select(_ => Unit.Value);
And here's the result:
System.ArgumentException: Error binding to target method. at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure) at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method) at System.Reactive.Linq.Observable.<>c__DisplayClass2c0`2.<FromEvent>b__2be(IObserver`1 observer) at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext, Action`1 onError, Action onCompleted) at System.Reactive.Linq.Observable.<>c__DisplayClass413`2.<Select>b__411(IObserver`1 observer) at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext, Action`1 onError, Action onCompleted) at System.Reactive.Linq.Observable.<>c__DisplayClass302`1.<>c__DisplayClass304.<Merge>b__2fc(IObservable`1 innerSource) at System.Reactive.AnonymousObserver`1.Next(T value) at System.Reactive.AbstractObserver`1.OnNext(T value) at System.Reactive.AnonymousObservable`1.AutoDetachObserver.Next(T value) at System.Reactive.AbstractObserver`1.OnNext(T value) at System.Reactive.Linq.Observable.<>c__DisplayClass29e`1.<Subscribe>b__29d(Action self) at System.Reactive.Concurrency.Scheduler.<Schedule>b__0(Action`1 _action, Action`1 self) at System.Reactive.Concurrency.Scheduler.<>c__DisplayClassb`1.<InvokeRec1>b__8(TState state1) at System.Reactive.Concurrency.Scheduler.InvokeRec1[TState](IScheduler scheduler, Pair`2 pair) at System.Reactive.Concurrency.ImmediateScheduler.Schedule[TState](TState state, Func`3 action) at System.Reactive.Concurrency.Scheduler.Schedule[TState](IScheduler scheduler, TState state, Action`2 action) at System.Reactive.Concurrency.Scheduler.Schedule(IScheduler scheduler, Action`1 action) at System.Reactive.Linq.Observable.Subscribe[TSource](IEnumerable`1 source, IObserver`1 observer, IScheduler scheduler) at System.Reactive.Linq.Observable.<>c__DisplayClass2d7`1.<ToObservable>b__2d6(IObserver`1 observer) at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext, Action`1 onError, Action onCompleted) at System.Reactive.Linq.Observable.<>c__DisplayClass302`1.<Merge>b__2fb(IObserver`1 observer) at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext, Action`1 onError, Action onCompleted) at System.Reactive.Linq.Observable.<>c__DisplayClass413`2.<Select>b__411(IObserver`1 observer) at System.Reactive.AnonymousObservable`1.<>c__DisplayClass1.<Subscribe>b__0() at System.Reactive.Concurrency.Scheduler.Invoke(IScheduler scheduler, Action action) at System.Reactive.Concurrency.ScheduledItem`2.InvokeCore() at System.Reactive.Concurrency.ScheduledItem`1.Invoke() at System.Reactive.Concurrency.CurrentThreadScheduler.Trampoline.Run() at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, TimeSpan dueTime, Func`3 action) at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, Func`3 action) at System.Reactive.Concurrency.Scheduler.Schedule(IScheduler scheduler, Action action) at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext, Action`1 onError, Action onCompleted) at System.ObservableExtensions.Subscribe[TSource](IObservable`1 source, Action`1 onNext) at ReactiveUI.Sample.Views.BlockTimerWindow..ctor(BlockItem Model) in C:\Users\Administrator\Dropbox\ReactiveUI_External\ReactiveUI.Sample\ReactiveUI.Sample\Views\BlockTimerWindow.xaml.cs:line 44
Any clues?
Tuesday, May 3, 2011 5:13 PM
Answers
-
Use FromEvent for events structurally don't look like a .NET event pattern (i.e. not based on sender, event args), and use FromEventPattern for the pattern-based ones. The sample code show for FromEvent above violates this distinction and uses an EventHandler inside (which indicates the use of the pattern). Does this make sense?
using (Microsoft.Sql.Cloud.DataProgrammability.Rx) { Signature.Emit("Bart De Smet"); }- Proposed as answer by Bart De Smet [MSFT] Friday, May 20, 2011 6:36 PM
- Marked as answer by Bart De Smet [MSFT] Friday, November 11, 2011 9:00 PM
Friday, May 20, 2011 6:35 PM
All replies
-
I duplicated the issue, but then changed it to use Observable.FromEventPattern instead, and it works.Tuesday, May 3, 2011 7:51 PM
-
The code for FromEvent should be something like this:
public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs { if (addHandler == null) { throw new ArgumentNullException("addHandler"); } if (removeHandler == null) { throw new ArgumentNullException("removeHandler"); } return Observable.Create<TEventArgs>(delegate(IObserver<TEventArgs> observer) { EventHandler<TEventArgs> firstArgument = new EventHandler<TEventArgs>((_, args) => observer.OnNext(args)); TDelegate d = (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), firstArgument, typeof(EventHandler<TEventArgs>).GetMethod("Invoke")); addHandler(d); return Disposable.Create(delegate { removeHandler(d); }); }); }
- Proposed as answer by Richard Hein Friday, May 6, 2011 12:11 AM
- Unproposed as answer by Bart De Smet [MSFT] Friday, May 20, 2011 6:34 PM
Wednesday, May 4, 2011 7:03 PM -
Another thread http://social.msdn.microsoft.com/Forums/en-US/rx/thread/4f6c28ce-4ae9-470b-99bc-182e1afa712e mentions that FromEvent doesn't work with WPF in the latest drop. User FromEventPattern instead.
Dan Sullivan- Proposed as answer by Bart De Smet [MSFT] Friday, May 20, 2011 6:33 PM
Monday, May 9, 2011 1:10 AM -
Use FromEvent for events structurally don't look like a .NET event pattern (i.e. not based on sender, event args), and use FromEventPattern for the pattern-based ones. The sample code show for FromEvent above violates this distinction and uses an EventHandler inside (which indicates the use of the pattern). Does this make sense?
using (Microsoft.Sql.Cloud.DataProgrammability.Rx) { Signature.Emit("Bart De Smet"); }- Proposed as answer by Bart De Smet [MSFT] Friday, May 20, 2011 6:36 PM
- Marked as answer by Bart De Smet [MSFT] Friday, November 11, 2011 9:00 PM
Friday, May 20, 2011 6:35 PM