C# 反应式扩展和IDisposable管理
我正在尝试使用Microsoft.Management.Infrastructure的C# 反应式扩展和IDisposable管理,c#,.net,.net-core,system.reactive,C#,.net,.net Core,System.reactive,我正在尝试使用Microsoft.Management.Infrastructure的Async版本,但我很难弄清楚如何使用反应式扩展进行会话管理 以下是一些背景: 可以使用创建CIM会话,它返回IObservable CimSession.CreateAsync返回一个 cimsynchdelegatedobservable,因此当不再需要时,必须手动处理CimSession 在获得CimSession的句柄后,我尝试运行WQL查询,例如使用session.queryInstanceAsyn
Async
版本,但我很难弄清楚如何使用反应式扩展进行会话管理
以下是一些背景:
- 可以使用创建CIM会话,它返回
IObservable
返回一个CimSession.CreateAsync
,因此当不再需要时,必须手动处理cimsynchdelegatedobservable
CimSession
- 在获得
的句柄后,我尝试运行WQL查询,例如使用CimSession
session.queryInstanceAsync(@“root\cimv2”、“WQL”、“从Win32\U ComputerSystem中选择用户名”)
CimSession
返回的是Task
s而不是Observable
s,那么代码将非常简单:
使用var session=CimSession.CreateAsync(“.”);
var results=session.queryInstanceAsync(@“root\cimv2”、“WQL”、“从Win32_ComputerSystem中选择用户名”);
但是由于Async
方法是使用Observable
s实现的,我不知道如何将其转化为Observable
s的惯用用法。当然,我可以使用System.Reactive.Linq.Observable.ForEachAsync
将我的方法转换为任务
,但我想学习如何正确使用Observable
总而言之,我的问题是:
- 将
的生存期绑定到CimSession
可观察的
- 如果没有订阅者,如何确保处置
?我应该强制至少一个订阅者,但使用工厂方法吗CimSession
- 当
的结果到达时,如何处理queryInstanceAsync
可观察到的内容CimSession
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;
IObservable查询=
来自CimSession.CreateAsync(“.”)中的会话
从可观察的x开始。使用(
()=>会议,
s=>s.QueryInstanceAsync(@“root\cimv2”、“WQL”、“从Win32\U计算机系统中选择用户名”))
从可观察的y开始。使用(
()=>x,
z=>Observable.Return(z.GetCimSessionComputerName())
选择y;
如果这样做有效,我建议将其包装在单独的类中:
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;
}
公共静态类CimSessionEx
{
公共静态IObservable CreateObservable(字符串computerName、字符串namespaceName、字符串queryDialect、字符串queryExpression、函数工厂)=>
从CimSession.CreateAsync(computerName)中的会话
使用(()=>session,s=>s.QueryInstanceAsync(namespaceName,queryDialect,queryExpression))
使用(()=>实例,工厂)
选择y;
}
然后你可以这样使用它:
IObservable<string> query =
CimSessionEx.CreateObservable(
".",
@"root\cimv2",
"WQL",
"SELECT Username FROM Win32_ComputerSystem",
i => Observable.Return(i.GetCimSessionComputerName()));
IObservable查询=
CimSessionEx.CreateObservable(
".",
@“根目录\cimv2”,
“WQL”,
“从Win32\u计算机系统中选择用户名”,
i=>Observable.Return(i.GetCimSessionComputerName());