Showing posts with label Reactive. Show all posts
Showing posts with label Reactive. Show all posts

Thursday, May 5, 2011

My first Rx Attempt revisited

I have recently rediscovered my custom code analysis rules which included one that no longer compiles. The Rx team has made sweeping and breaking changes to the structure and namespaces in Rx. How difficult was the code update? 2 references removed, 1 added, and a single MethodName changed.

I cleaned up the code, and discovered many improvements along the way.
I do wish I could find a cleaner way to do this:

var whenMethodsFound = Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
 act => foundMethods.CollectionChanged += act,
  act => foundMethods.CollectionChanged -= act);

Idea:
Add a mapping extension in extension method class
Great for simple on the go, but manual for every class you want to do this with.

Which would look like this

public static IObservable<IEvent<PageEventArgs>> GetPublishingPageEvent(this DataFactory dataFactory)
   {
       return Observable.FromEvent((EventHandler<PageEventArgs> h) => new PageEventHandler(h), 
                                h => dataFactory.PublishingPage += h, 
                                h => dataFactory.PublishingPage -= h);
  }


Thursday, September 9, 2010

My first Rx attempt

I think I overshot for a first attempt by far and I'm not sure how to validate the efficiency/concurrency of the code. However, here is Rx that so far as I've used it appears to correctly do recursive producer-consumer iteration of a call graph.



 public override ProblemCollection Check(TypeNode type)
    {
      Debug.WriteLine("Checking type:"+type.FullName);
      var initializer = type.Members.OfType<Method>( ).FirstOrDefault(x => x.FullName==type.FullName+".InitializeComponent");
 
      if (initializer==null)
        return null;
      Debug.WriteLine(initializer.FullName);
      var constructorsWithNoInitCall = type.Members.OfType<Method>( ).Where(m => m.NodeType==NodeType.InstanceInitializer).ToList( );
      var visitedMethods = new HashSet<string>( );
      var foundMethods = new ObservableHashSet<Method>( );
 
      var whenMethodsFound = Observable.FromEvent<NotifyCollectionChangedEventArgs>(foundMethods, "CollectionChanged");
 
      whenMethodsFound.Subscribe(
        e =>
        {
          switch (e.EventArgs.Action)
          {
            case NotifyCollectionChangedAction.Add:
              if (constructorsWithNoInitCall.Any( ))
                Parallel.ForEach(e.EventArgs.NewItems.Cast<Method>( ).Where(m => visitedMethods.Any(v => v==m.FullName)==false),
                  i =>
                  {
 
                    lock (visitedMethods)
                    {
                      if (visitedMethods.Contains(i.FullName))
                        return;
                      visitedMethods.Add(i.FullName);
 
                    }
                    Debug.WriteLine("Visiting:"+i.FullName);
                    var callers = (CallGraph.CallersFor(i));
                    constructorsWithNoInitCall.RemoveAll(x => callers.Any(c => x.FullName==c.FullName));
                    if (constructorsWithNoInitCall.Any( ))
                      foreach (var item in callers.Where(c => visitedMethods.Any(v => v==c.FullName)==false))
                      {
                        foundMethods.Add(item);
                      }
                  });
              break;
            default:
              break;
          }
        }
        );
      foundMethods.Add(initializer);
 
 
      ReportProblem(constructorsWithNoInitCall, type);
 
      return Problems;
    }