Jani
Jani

Reputation: 1148

Reactive Extensions and IDisposable management

I'm trying to use Async versions of Microsoft.Management.Infrastructure, but I'm having hard time figuring out how to do session management with Reactive Extensions.

Here's some background:

If CimSession returned Tasks instead of Observables, the code would be pretty straightforward:

using var session = CimSession.CreateAsync(".");
var results = session.QueryInstancesAsync(@"root\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem");

But as the Async methods are implemented using Observables, I'm not sure how to translate this to idiomatic usage of Observables. Sure I could translate my methods to Tasks using System.Reactive.Linq.Observable.ForEachAsync, but I'd like to learn how to use Observables properly.

To sum it up, my questions would be:

Upvotes: 1

Views: 205

Answers (1)

Enigmativity
Enigmativity

Reputation: 117064

It's a bit of a whacky interface, but give this a go and let me know if it works:

IObservable<string> query =
    from session in CimSession.CreateAsync(".")
    from x in Observable.Using(
        () => session,
        s => s.QueryInstancesAsync(@"root\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem"))
    from y in Observable.Using(
        () => x,
        z => Observable.Return(z.GetCimSessionComputerName()))
    select y;

If that works, I'd suggest wrapping it in a separate class:

public static class CimSessionEx
{
    public static IObservable<T> CreateObservable<T>(string computerName, string namespaceName, string queryDialect, string queryExpression, Func<CimInstance, IObservable<T>> factory) =>
        from session in CimSession.CreateAsync(computerName)
        from instance in Observable.Using(() => session, s => s.QueryInstancesAsync(namespaceName, queryDialect, queryExpression))
        from y in Observable.Using(() => instance, factory)
        select y;
}

Then you could use it like this:

IObservable<string> query =
    CimSessionEx.CreateObservable(
        ".",
        @"root\cimv2",
        "WQL",
        "SELECT Username FROM Win32_ComputerSystem",
        i => Observable.Return(i.GetCimSessionComputerName()));

Upvotes: 1

Related Questions