[英]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.我正在尝试使用
Microsoft.Management.Infrastructure
Async
版本,但我很难弄清楚如何使用 Reactive Extensions 进行会话管理。
Here's some background:这是一些背景:
CimSession.CreateAsync
, which returns IObservable
CimSession.CreateAsync
创建一个 CIM 会话,它返回IObservable
CimSession.CreateAsync
returns a CimAsyncResult<T>
, which wraps CimAsyncDelegatedObservable<T>
CimSession.CreateAsync
返回一个CimAsyncResult<T>
,它包装CimAsyncDelegatedObservable<T>
CimAsyncDelegatedObservable<T>
does not dispose CimSession
at any point, and thus one must manually dispose CimSession
when it is not needed anymore. CimAsyncDelegatedObservable<T>
不会在任何时候处理CimSession
,因此当不再需要CimSession
时必须手动处理它。CimSession
, I'm trying to run a WQL query using QueryInstancesAsync
, for example session.QueryInstancesAsync(@"root\\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem")
CimSession
句柄后,我尝试使用QueryInstancesAsync
运行 WQL 查询,例如session.QueryInstancesAsync(@"root\\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem")
If CimSession
returned Task
s instead of Observable
s, the code would be pretty straightforward:如果
CimSession
返回Task
而不是Observable
,代码将非常简单:
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 Observable
s, I'm not sure how to translate this to idiomatic usage of Observable
s.但是由于
Async
方法是使用Observable
实现的,我不确定如何将其转换为Observable
的惯用用法。 Sure I could translate my methods to Task
s using System.Reactive.Linq.Observable.ForEachAsync
, but I'd like to learn how to use Observables properly.当然我可以使用
System.Reactive.Linq.Observable.ForEachAsync
将我的方法转换为Task
,但我想学习如何正确使用 Observables。
To sum it up, my questions would be:总结一下,我的问题是:
CimSession
to Observable
CimSession
生命周期绑定到Observable
CimSession
gets disposed, if there are no subscribers?CimSession
得到处理? Should I force at least one subscriber, but having factory method?CimSession
observable when results for QueryInstancesAsync
arrive?QueryInstancesAsync
结果到达时,如何处理CimSession
observable?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()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.