gpt4 book ai didi

f# - 如何使用 F# WMI 类型提供程序连续获取计数器值

转载 作者:行者123 更新时间:2023-12-02 21:10:49 25 4
gpt4 key购买 nike

您好,我正在尝试 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 类型提供程序是否有类似的东西?谢谢!

最佳答案

如果你不想阻塞当前线程,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

该脚本生成例如

At 27.09.2016 10:24:10: free 8'053'600 KB
At 27.09.2016 10:24:11: free 8'053'604 KB
At 27.09.2016 10:24:13: free 8'053'600 KB
At 27.09.2016 10:24:14: free 8'053'604 KB
At 27.09.2016 10:24:15: free 8'054'472 KB
At 27.09.2016 10:24:16: free 8'054'468 KB
At 27.09.2016 10:24:17: free 8'054'496 KB
At 27.09.2016 10:24:18: free 8'054'480 KB
At 27.09.2016 10:24:20: free 8'054'492 KB

关于f# - 如何使用 F# WMI 类型提供程序连续获取计数器值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com