C# 异步(工厂)方法和 LINQ
C# Async (Factory) Methods & LINQ
我正在寻找一种合适的方法来设计我的代码。我有一个通过以下方式创建的设备列表:
public void LoadDevices()
{
using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath))
deviceList = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
where (string)deviceElem.Attribute("type") == "mks247"
select (SmartCatDeviceBase)new mks247Device(
(string)deviceElem.Attribute("ip"),
(string)deviceElem.Attribute("name"),
(string)deviceElem.Attribute("id"),
(bool)deviceElem.Attribute("autoconnect")
)).ToList();
}
必须对 SmartCatDeviceBase 进行类型转换,因为我有更多不同类型的设备(具有相同的基础-class)进入该列表。
现在的问题是 "autoconnect":它需要设备打开异步网络连接,这不应该在构造函数中完成 (as Stephen Cleary states here)。
因此我想求助于某种类似工厂的东西:
private async Task<SmartCatDeviceBase> Createmks247DeviceAsync(string host, string name, string id, bool autoconnect = true)
{
mks247Device dev = new mks247Device(host, name, id); // Now without the autoconnect, that shouldn't be in the constructor.
// Connect.
if (autoconnect)
{
bool connected = await dev.ConnectAsync();
// Begin to poll for data.
dev.BeginPolling();
}
return dev;
}
所以问题是:我怎样才能使该代码工作?因为使用 Createmks247DeviceAsync 而不是 new mks247Device() 在我的 LINQ 代码中不起作用:
类型"System.Threading.Tasks.Task"无法转换为"SmartCatDeviceBase"。
在select 语句中使用 await 关键字也是不可能的...
或者有没有其他方法可以正确设计这样的代码?在构造函数中设置自动更正标志然后稍后连接 "from outside" 似乎违反了 OOP:当有自动连接选项时,我希望在将其设置为真时反对自动创建...
提前致谢!新年快乐!
一路将方法转换为异步。
Select 所有使用 Linq 的任务,然后等待 Task.WhenAll
连接它们。
public async Task LoadDevicesAsync() {
using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath)) {
var getdeviceListTasks = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
where (string)deviceElem.Attribute("type") == "mks247"
select Createmks247DeviceAsync(
(string)deviceElem.Attribute("ip"),
(string)deviceElem.Attribute("name"),
(string)deviceElem.Attribute("id"),
(bool)deviceElem.Attribute("autoconnect")
));
var devices = await Task.WhenAll(getdeviceListTasks);
deviceList = devices.ToList();
}
}
我正在寻找一种合适的方法来设计我的代码。我有一个通过以下方式创建的设备列表:
public void LoadDevices()
{
using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath))
deviceList = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
where (string)deviceElem.Attribute("type") == "mks247"
select (SmartCatDeviceBase)new mks247Device(
(string)deviceElem.Attribute("ip"),
(string)deviceElem.Attribute("name"),
(string)deviceElem.Attribute("id"),
(bool)deviceElem.Attribute("autoconnect")
)).ToList();
}
必须对 SmartCatDeviceBase 进行类型转换,因为我有更多不同类型的设备(具有相同的基础-class)进入该列表。
现在的问题是 "autoconnect":它需要设备打开异步网络连接,这不应该在构造函数中完成 (as Stephen Cleary states here)。
因此我想求助于某种类似工厂的东西:
private async Task<SmartCatDeviceBase> Createmks247DeviceAsync(string host, string name, string id, bool autoconnect = true)
{
mks247Device dev = new mks247Device(host, name, id); // Now without the autoconnect, that shouldn't be in the constructor.
// Connect.
if (autoconnect)
{
bool connected = await dev.ConnectAsync();
// Begin to poll for data.
dev.BeginPolling();
}
return dev;
}
所以问题是:我怎样才能使该代码工作?因为使用 Createmks247DeviceAsync 而不是 new mks247Device() 在我的 LINQ 代码中不起作用:
类型"System.Threading.Tasks.Task"无法转换为"SmartCatDeviceBase"。
在select 语句中使用 await 关键字也是不可能的...
或者有没有其他方法可以正确设计这样的代码?在构造函数中设置自动更正标志然后稍后连接 "from outside" 似乎违反了 OOP:当有自动连接选项时,我希望在将其设置为真时反对自动创建...
提前致谢!新年快乐!
一路将方法转换为异步。
Select 所有使用 Linq 的任务,然后等待 Task.WhenAll
连接它们。
public async Task LoadDevicesAsync() {
using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath)) {
var getdeviceListTasks = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
where (string)deviceElem.Attribute("type") == "mks247"
select Createmks247DeviceAsync(
(string)deviceElem.Attribute("ip"),
(string)deviceElem.Attribute("name"),
(string)deviceElem.Attribute("id"),
(bool)deviceElem.Attribute("autoconnect")
));
var devices = await Task.WhenAll(getdeviceListTasks);
deviceList = devices.ToList();
}
}