【发布时间】:2018-09-04 05:43:52
【问题描述】:
我阅读了很多关于异步方法的帖子,但仍然......我对此有点困惑。所以也许有人可以帮助我处理我的案子。现在我的代码没有抛出任何错误,但我知道我的代码不好,因为我使用 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(...) 在 Machine 类中:
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;
}
}
}
还有 Relation 类中的 WMI select 方法(其实这个方法应该是真正异步的,因为 WMI select 有时会很慢):
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;
}
【问题讨论】:
-
Blaato,真正的问题是什么?是您无法处理任务中的异常吗?
-
@KozhevnikovDmitry 不,例外很好,但我知道异步 void 是一个糟糕的解决方案 => LoadMachienData(),所以我想知道如何正确地做到这一点,第二个是在这个解决方案 a 不能等待 LoadmachineData 方法中的所有任务完成。所以我想在上面的示例中运行任务,异步运行它们并等待所有这些任务完成。
标签: c# asynchronous methods task