Я прочитал много постов об асинхронных методах, но все же ... Я немного запутался по этому поводу. Так что, возможно, кто-то может помочь мне с моим делом. Прямо сейчас мой код не выдает никакой ошибки, но я знаю, что мой код не хорош, потому что я использую async void, и я не могу ждать, пока все мои задачи будут выполнены.
Итак, кто-то может помочь мне отредактировать этот код:
В своем классе я создаю отношение:
Relation rel = new Relation(cb_MachineToConnect.Text);
В классе отношений:
public Relation(string machineAddress)
{
isAsctive = true;
idCount++;
relationID = idCount;
machine = new Machine(machineAddress);
//I'm using WMI for gettig data from remote machine
scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", machineAddress));
scope.Options.Timeout = TimeSpan.FromSeconds(timeOut);
//In this method, I need run async part of code - WMI selects
LoadMachineData();
}
Код метода LoadMachineData:
private async void LoadMachineData()
{
try
{
scope.Connect();
try
{
//List<Task> taskList = new List<Task>();
foreach (KeyValuePair<SelectQueryName, SelectQuery> select in SelectQueryes)
{
//And this is it.. I need to run this methods async for better performance. SelectFromWMI is in Relation class and SetWMIproiperties is in Machine class
await Task.Run(() => machine.SetWMIProperties(select.Key, SelectFromWMI(select.Value, scope)));
//taskList.Add(t);
//machine.SetWMIProperties(select.Key, SelectFromWMI(select.Value, scope));
}
//I also want to wait for all created Tasks completion, but with this code it is not possible
//Task.WaitAll(taskList.ToArray());
}
catch (Exception ex)
{
EventNotifier.LogOnScreen(string.Format("{0}, viz: {1}", ErrorList.GetEIbyID(15).definition, ex.Message));
EventNotifier.Log(ex, ErrorList.GetEIbyID(15));
}
}
catch (Exception ex)
{
EventNotifier.LogOnScreen(string.Format("{0}, viz: {1}", ErrorList.GetEIbyID(16).definition, ex.Message));
EventNotifier.Log(ex, ErrorList.GetEIbyID(17));
}
}
SetWMIProperties (...) в классе машины:
public void SetWMIProperties(SelectQueryName queryName, List<Dictionary<string, string>> propertiesData)
{
foreach (Dictionary<string, string> result in propertiesData)
{
switch (queryName)
{
case SelectQueryName.DiskModel:
disks.Add(result["Model"]);
break;
case SelectQueryName.Drives:
drives.Add(new Drive { Name = result["Name"], FreeSpace = Convert.ToInt64(result["FreeSpace"]), Size = Convert.ToInt64(result["Size"]) });
break;
case SelectQueryName.OS:
operatingSystem = new OS { BuildNumber = result["BuildNumber"], ProductName = result["Caption"], BitVersion = (result["OSArchitecture"].Contains(((int)OSBitVersion.Win32).ToString())) ? OSBitVersion.Win32 : OSBitVersion.Win64 };
break;
case SelectQueryName.Processor:
processor = result["Name"];
break;
case SelectQueryName.RAM:
ram = new RAM { TotalVisibleMemorySize = Convert.ToInt64(result["TotalVisibleMemorySize"]), FreePhysicalMemory = Convert.ToInt64(result["FreePhysicalMemory"]) };
break;
}
}
}
И метод выбора WMI в классе Relation (на самом деле этот метод должен быть действительно асинхронным, потому что иногда выбор WMI может быть очень медленным):
private static List<Dictionary<string, string>> SelectFromWMI(SelectQuery select, ManagementScope wmiScope)
{
List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiScope, select);
ManagementObjectCollection objectCollection = searcher.Get();
foreach (ManagementObject managementObject in objectCollection)
{
result.Add(new Dictionary<string, string>());
foreach (PropertyData property in managementObject.Properties)
{
result.Last().Add(property.Name, property.Value.ToString());
}
}
return result;
}