Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6702463
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T07:03:25+00:00 2026-05-26T07:03:25+00:00

I have a RIA Services data service that has several function calls that look

  • 0

I have a RIA Services data service that has several function calls that look like this:

public InvokeOperation<T> SomeFunc(
    SomeData data,
    Action<InvokeOperation<T>> callback,
    object userState)

How would I use this with Reactive Extensions so I can subscribe to the callback and get the InvokeOperation result?


Update: here is my current implementation of Enigmativity’s hybrid solution. I needed the actual InvokeOperation not just the value since the InvokeOperation UserState can be valuable. It should be noted that I haven’t tested error handling at all.

public static class ObservableEx
{
      public static IObservable<InvokeOperation<T>> ObservableInvokeOperation<T, Tdat> (
         Func<Tdat, Action<InvokeOperation<T>>, object, InvokeOperation<T>> func,
         Tdat data,
         System.Reactive.Concurrency.IScheduler scheduler )
      {
         return
             Observable.Defer<InvokeOperation<T>>( () =>
                 FromCallbackPattern<Tdat, T>( func, scheduler )
                     .Invoke( data ) );
      }

      private static Func<P, IObservable<InvokeOperation<T>>> FromCallbackPattern<P, T> (
          Func<P, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
          IScheduler scheduler )
      {
         return p =>
         {
            var subject = new AsyncSubject<InvokeOperation<T>>();
            try
            {
               call( p, iot =>
               {
                  if ( iot.HasError )
                  {
                     subject.OnError( iot.Error );
                  }
                  else
                  {
                     subject.OnNext( iot );
                     subject.OnCompleted();
                  }
               }, p );
            }
            catch ( Exception ex )
            {
               subject.OnError( ex );
            }
            return subject.ObserveOn( scheduler );
         };
      }   
}

useage given function

public InvokeOperation<int> SomeFunc(SomeData data, Action<InvokeOperation<int>> callback, object userState)

var myobs = ObservableEx.ObservableInvokeOperation<int, SomeData>( myRIAContext.SomeFunc, data, Scheduler.ThreadPool );

This works great for any function that with matches the given function signature. Unfortunately now I’ve run into some variations such as

Func<T1, Action<InvokeOperation<T>>, object>
Func<T1, T2, Action<InvokeOperation<T>>, object>

Anyone have any suggestions to convert this to be able to handle any InvokeOperation method I want to throw at it?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T07:03:26+00:00Added an answer on May 26, 2026 at 7:03 am

    EDIT1: See below for a hybrid solution based on Paul Betts’ answer and mine.

    EDIT2: See below for a “third-generation” solution based on the OP’s update.


    The callback is a little difficult to deal with and I must say that turning this into an observable is a good way to go.

    I’ve got an approach that worked for me.

    The basic approach is to turn the SomeFunc operation into a Func<T> and then call Observable.Start on that. I’ve wrapped this in Observable.Create to keep it clean and I’ve added error handling. I’ve done basic testing, but nothing too robust.

    Consuming the code looks like this:

    var obs = service.SomeObservableFunc(new SomeData(), Scheduler.ThreadPool);
    obs.Subscribe(t => { /* success */ }, ex => { /* error */ });
    

    I’ve assumed that your RIA service class is RiaService<T> and built the SomeObservableFunc extension method like this:

        public static IObservable<T> SomeObservableFunc<T>(
            this RiaService<T> service,
            SomeData data,
            IScheduler scheduler)
        {
            return Observable.Create<T>(o =>
            {
                var error = (Exception)null;
                Func<T> call = () =>
                {
                    var result = default(T);
                    var mre = new ManualResetEvent(false);
                    Action<InvokeOperation<T>> callback = iot =>
                    {
                        try
                        {
                            if (iot.HasError)
                            {
                                error = iot.Error;
                            }
                            else
                            {
                                result = iot.Value;
                            }
                        }
                        catch (Exception ex)
                        {
                            error = ex;
                        }
                        finally
                        {
                            mre.Set();
                        }
                    };
                    try
                    {
                        service.SomeFunc(data, callback, null);
                        mre.WaitOne();
                    }
                    catch (Exception ex)
                    {
                        error = ex;
                    }
                    return result;
                };
    
                return Observable
                    .Start(call, scheduler)
                    .Subscribe(t =>
                    {
                        try
                        {
                            if (error == null)
                            {
                                o.OnNext(t);
                            }
                            else
                            {
                                o.OnError(error);
                            }
                        }
                        catch (Exception ex)
                        {
                            o.OnError(ex);
                        }
                    }, ex => o.OnError(ex), () =>
                    {
                        if (error == null)
                        {
                            o.OnCompleted();
                        }
                    });
            });
        }
    

    Yell out if this works for you.


    EDIT1

    I liked Paul Betts’ solution because it didn’t use ManualResetEvent, but it didn’t compile and also didn’t handle internal errors that could occur during the RIA service call, so I’ve created the follow hybrid solution.

    My extension method now looks like this:

        public static IObservable<T> SomeObservableFunc<T>(
            this RiaService<T> service,
            SomeData data,
            IScheduler scheduler)
        {
            return
                Observable.Defer<T>(() =>
                    FromCallbackPattern<SomeData, T>(service.SomeFunc, scheduler)
                        .Invoke(data));
        }
    

    And this uses the reworked FromCallbackPattern originally created by Paul Betts:

        private static Func<P, IObservable<T>> FromCallbackPattern<P, T>(
            Func<P, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return p =>
            {
                var subject = new AsyncSubject<T>();
                try
                {
                    call(p, iot =>
                    {
                        if (iot.HasError)
                        {
                            subject.OnError(iot.Error);
                        }
                        else
                        {
                            subject.OnNext(iot.Value);
                            subject.OnCompleted();
                        }
                    }, null);
                }
                catch (Exception ex)
                {
                    subject.OnError(ex);
                }
                return subject.ObserveOn(scheduler);
            };
        }
    

    It works against my test code and I think this is a nicer overall solution.


    EDIT2

    This version of the solution is designed to allow differing number of parameters plus the user state to be passed to the FromCallbackPattern extension methods.

    I started with this general purpose FromCallbackPattern extension method:

        public static IObservable<InvokeOperation<T>> FromCallbackPattern<T>(
            this Action<Action<InvokeOperation<T>>> call,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
            {
                var subject = new AsyncSubject<InvokeOperation<T>>();
                try
                {
                    call(iot =>
                    {
                        subject.OnNext(iot);
                        subject.OnCompleted();
                    });
                }
                catch (Exception ex)
                {
                    subject.OnError(ex);
                }
                return subject.ObserveOn(scheduler);
            });
        }
    

    Then I needed a series of private Reduce extension methods to reduce the various service calls down to Action<Action<InvokeOperation<T>>> delegates:

        private static Action<Action<InvokeOperation<T>>> Reduce<T>(
            this Func<Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            object state)
        {
            return a => call(a, state);
        }
    
        private static Action<Action<InvokeOperation<T>>> Reduce<P, T>(
            this Func<P, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            P p, object state)
        {
            return a => call(p, a, state);
        }       
    
        private static Action<Action<InvokeOperation<T>>> Reduce<P1, P2, T>(
            this Func<P1, P2, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            P1 p1, P2 p2, object state)
        {
            return a => call(p1, p2, a, state);
        }
    
        private static Action<Action<InvokeOperation<T>>> Reduce<P1, P2, P3, T>(
            this Func<P1, P2, P3, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            P1 p1, P2 p2, P3 p3, object state)
        {
            return a => call(p1, p2, p3, a, state);
        }
    
        private static Action<Action<InvokeOperation<T>>> Reduce<P1, P2, P3, P4, T>(
            this Func<P1, P2, P3, P4, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            P1 p1, P2 p2, P3 p3, P4 p4, object state)
        {
            return a => call(p1, p2, p3, p4, a, state);
        }
    

    Now I can write the plain FromCallbackPattern extension methods:

        public static Func<object, IObservable<InvokeOperation<T>>> FromCallbackPattern<T>(
            this Func<Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return o => call.Reduce(o).FromCallbackPattern(scheduler);
        }
    
        public static Func<P, object, IObservable<InvokeOperation<T>>> FromCallbackPattern<P, T>(
            this Func<P, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return (p, o) => call.Reduce(p, o).FromCallbackPattern(scheduler);
        }
    
        public static Func<P1, P2, object, IObservable<InvokeOperation<T>>> FromCallbackPattern<P1, P2, T>(
            this Func<P1, P2, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return (p1, p2, o) => call.Reduce(p1, p2, o).FromCallbackPattern(scheduler);
        }
    
        public static Func<P1, P2, P3, object, IObservable<InvokeOperation<T>>> FromCallbackPattern<P1, P2, P3, T>(
            this Func<P1, P2, P3, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return (p1, p2, p3, o) => call.Reduce(p1, p2, p3, o).FromCallbackPattern(scheduler);
        }
    
        public static Func<P1, P2, P3, P4, object, IObservable<InvokeOperation<T>>> FromCallbackPattern<P1, P2, P3, P4, T>(
            this Func<P1, P2, P3, P4, Action<InvokeOperation<T>>, object, InvokeOperation<T>> call,
            IScheduler scheduler)
        {
            return (p1, p2, p3, p4, o) => call.Reduce(p1, p2, p3, p4, o).FromCallbackPattern(scheduler);
        }
    

    And then, finally, the original SomeObservableFunc/ObservableInvokeOperation extension methods (now also renamed to FromCallbackPattern):

        public static IObservable<InvokeOperation<T>> FromCallbackPattern<T>(
            this RiaService<T> service,
            Func<RiaService<T>, Func<Action<InvokeOperation<T>>, object, InvokeOperation<T>>> call,
            object state,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
                call(service).FromCallbackPattern(scheduler)
                    .Invoke(state));
        }
    
        public static IObservable<InvokeOperation<T>> FromCallbackPattern<P, T>(
            this RiaService<T> service,
            Func<RiaService<T>, Func<P, Action<InvokeOperation<T>>, object, InvokeOperation<T>>> call,
            P p, object state,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
                call(service).FromCallbackPattern(scheduler)
                    .Invoke(p, state));
        }
    
        public static IObservable<InvokeOperation<T>> FromCallbackPattern<P1, P2, T>(
            this RiaService<T> service,
            Func<RiaService<T>, Func<P1, P2, Action<InvokeOperation<T>>, object, InvokeOperation<T>>> call,
            P1 p1, P2 p2, object state,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
                call(service).FromCallbackPattern(scheduler)
                    .Invoke(p1, p2, state));
        }
    
        public static IObservable<InvokeOperation<T>> FromCallbackPattern<P1, P2, P3, T>(
            this RiaService<T> service,
            Func<RiaService<T>, Func<P1, P2, P3, Action<InvokeOperation<T>>, object, InvokeOperation<T>>> call,
            P1 p1, P2 p2, P3 p3, object state,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
                call(service).FromCallbackPattern(scheduler)
                    .Invoke(p1, p2, p3, state));
        }   
    
        public static IObservable<InvokeOperation<T>> FromCallbackPattern<P1, P2, P3, P4, T>(
            this RiaService<T> service,
            Func<RiaService<T>, Func<P1, P2, P3, P4, Action<InvokeOperation<T>>, object, InvokeOperation<T>>> call,
            P1 p1, P2 p2, P3 p3, P4 p4, object state,
            IScheduler scheduler)
        {
            return Observable.Defer(() =>
                call(service).FromCallbackPattern(scheduler)
                    .Invoke(p1, p2, p3, p4, state));
        }           
    

    Obviously you need to replace the references to RiaService<T> with your RIA service class type.

    These methods can be called like this:

    IObservable<InvokeOperation<int>> obs1 =
        service
            .FromCallbackPattern(
                s => s.SomeFunc,
                new SomeData(),
                null, // user state
                Scheduler.ThreadPool);
    
    IObservable<InvokeOperation<int>> obs2 =
        service
            .FromCallbackPattern(
                s => s.SomeOtherFunc,
                42, "Hello", 3.14159265,
                null, // user state
                Scheduler.ThreadPool);
    

    Phew! How’s that now?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a complex RIA client that communicates with a WCF SOAP web service,
Environment: VS2010, SL4, RIA Services I have an SL4 UI that I developed against
I have a simple Silverlight application that use WCF RIA Services to communicate with
I have the following Ria Service define: namespace SilverlightTest.Web { [EnableClientAccess()] public class ContactService
I have this working and getting data. However, everytime I page it calls the
I am developing a RIA Domain Service that will use a POCO Entity Data
I have a WCF service (not RIA) that I access from Silverlight. The application
I have a WCF Data Service running that is exposing an EDM. There are
I have a Silverlight application that has a DataGrid and a DataPager. The data
I have a Silverlight / WCF RIA Services application that uses EF 4. Currently,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.