您好我正在尝试F#WMI类型提供程序代码示例,如下所示
type Local = WmiProvider<"localhost">
let data = Local.GetDataContext()
let memory = [for d in data.Win32_PerfFormattedData_PerfOS_Memory -> d.AvailableBytes]
这种情况下的内存是System.Nullable列表。那么问题是如何获得此列表的持续更新?目前我的代码看起来像这样
let printMemory () =
let rec outerLoop =
let memory = [for d in data.Win32_PerfFormattedData_PerfOS_Memory -> d.AvailableBytes]
let rec loop (values:Nullable<uint64> list) =
Thread.Sleep(1000)
match values with
|[] -> printfn "empty"
outerLoop
|h::t -> printfn "value = %d" h.Value
loop t
loop memory
outerLoop
所以我每次都要请求新的列表(内存),这是正确的方法吗? 例如,来自System.Diagnostics的PerformanceCounter计数器实现NextValue,WMI类型提供程序是否有类似的东西?谢谢!
答案 0 :(得分:1)
如果您不想阻止当前线程,Rx提供了一个很好的API来处理:
// nuget FSharp.Management
#I "packages/FSharp.Management/lib/net40"
// nuget System.Reactive
#I "packages/System.Reactive.Core/lib/net46"
#I "packages/System.Reactive.Linq/lib/net46"
#I "packages/System.Reactive.Interfaces/lib/net45"
#r "System.Management.dll"
#r "FSharp.Management.WMI.dll"
#r "System.Reactive.Core.dll"
#r "System.Reactive.Interfaces.dll"
#r "System.Reactive.Linq.dll"
open FSharp.Management
open System
open System.Reactive.Linq
open System.Runtime.InteropServices
open System.Text
[<DllImport("shlwapi.dll", CharSet = CharSet.Unicode)>]
extern int64 StrFormatKBSize(int64 qdw, [<MarshalAs(UnmanagedType.LPTStr)>] StringBuilder pszBuf, int cchBuf);
let bytesToString byteCount =
let sb = StringBuilder(32);
StrFormatKBSize(byteCount, sb, sb.Capacity) |> ignore
sb.ToString()
type Local = WmiProvider<"localhost">
let memory = Local.GetDataContext().Win32_PerfFormattedData_PerfOS_Memory
let freeMem() =
// I don't know the semantics of Win32_PerfFormattedData_PerfOS_Memory
// you might want to adjust the following
memory
|> Seq.choose (fun d -> d.AvailableBytes |> Option.ofNullable)
|> Seq.exactlyOne
let print m =
printfn "At %A: free %s" DateTime.UtcNow (bytesToString(int64 m))
// Immediately start to produce values every 1 second (on thread pool)
Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds 1.0)
|> Observable.map(fun _ -> freeMem())
// only propagate a value if it differs from the previous one
|> Observable.DistinctUntilChanged
|> Observable.subscribe print
// Causes a non-fatal error in VS Interactive, works in FSI
Console.ReadKey() |> ignore
此脚本产生例如
于2016年9月27日10:24:10:免费8&#39; 053&#39; 600 KB
在2016年9月27日10:24:11:免费8&#39; 053&#; 604 KB
在2016年9月27日10:24:13:免费8&#39; 053&#39; 600 KB
在2016年9月27日10:24:14:免费8&#39; 053&#; 604 KB
在2016年9月27日10:24:15:免费8&#39; 054&#39; 472▼ 在2016年9月27日10:24:16:免费8&#39; 054&#39; 468 KB
2016年9月27日10:24:17:免费8&#39; 054&#39; 49 在2016年9月27日10:24:18:免费8&#39; 054&#39; 480 KB
在2016年9月27日10:24:20:免费8&#39; 054&#39; 492
答案 1 :(得分:0)
您必须显式调用新值或使用刷新对象WmiSmoObject.Refresh
F#
abstract Refresh : unit -> unit
override Refresh : unit -> unit