// The Caller public async void StartShutdown(string wmiServer, string wmiNamespace, int action, UInt32 timeout, string comment, UInt32 reason, int delayBetweenAttempts) { var shutdownProgress = new Progress<WmiResult>(HandleShutdownProgress); Task shT = Wmi.RemoteShutdownAsync(wmiServer, wmiNamespace, action, timeout, comment,reason,delayBetweenAttempts, shutdownProgress); await shT; } //The Function public static async Task RemoteShutdownAsync(string wmiServer, string wmiNamespace, int action, UInt32 timeout, string comment, UInt32 reason, int delayBetweenAttempts, IProgress<WmiResult> wmiProgress) { WmiResult result = new WmiResult(wmiServer); result.AddResult(null, false, "RemoteShutdown", null); try { int count = 0; ManagementScope Scope = new ManagementScope(string.Format(@"\\{0}\{1}", wmiServer, wmiNamespace)); while (true) { await Task.Delay(delayBetweenAttempts); count += 1; if (Scope.IsConnected) { SelectQuery query = new SelectQuery("Win32_OperatingSystem"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(Scope, query); foreach (ManagementObject os in searcher.Get()) //Will only return the one current active O/S { // Obtain in-parameters for the method ManagementBaseObject inParams = os.GetMethodParameters("Win32ShutdownTracker"); // Add the input parameters. inParams["Flags"] = action; //sint32 = int inParams["Timeout"] = timeout; //UInt32 inParams["Comment"] = comment; //String inParams["ReasonCode"] = reason; //UInt32 // Execute the method and obtain the return values. //ManagementBaseObject outParams = os.InvokeMethod("Win32ShutdownTracker", inParams, null); //if (outParams["returnValue"].ToString() == "0") //{ // result.Message = "Ok"; // result.Success = true; // wmiProgress.Report(result); //} result.Message = "Ok"; result.Success = true; wmiProgress.Report(result); } break; } else { //Try to connect now Scope.Connect(); result.Message = count.ToString(); result.Success = false; wmiProgress.Report(result); } } } catch (Exception ex) { result.AddResult("Failed", false, "RemoteShutdown", ex.Message.ToString()); wmiProgress.Report(result); } }
Part of my WPF app needs to make a WMI connection to a remote machine, obtain an instance of a class and execute a method. All of this takes comparatively lots of time especially as I am hitting multiple servers and I don't want them to run consecutively and block.
I want to wrap all the above in a single asynch function which I will await
I have managed to understand large parts of the literature on Task\Await TAP, Await anything etc but am now in an endless loop of experimentation which is negatively impacting my will to live.
Can somebody tell me if this is possible and if so how?
So far I have 'faked' the function into believing it is asynch by including an 'await.Task.Delay()'. If I don't I get an error saying my asynch function must include an await. But I can't do that because none of the wmi methods are natively asynch.
See the attached code.
Many thanks
RD