嵌套的异步LINQ将子对象放入列表中

时间:2018-01-16 11:31:00

标签: c# xml linq asynchronous nested

我有以下XML:

<devices>
    <device name="DevName" type="mks247" ip="127.0.0.1" id="myID" autoconnect="1">
        <calibration name="test1" unit="mL/min" a="3" b="5"/>
        <calibration name="test2" unit="mL/min" a="2" b="3.4"/>
    </device>
</devices>

现在我使用此代码获取我的设备列表(到目前为止工作得很好)。请注意代码的异步字符:

var getmks247Task = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
                                 where (string)deviceElem.Attribute("type") == "mks247"
                                 select CreateAndConnectTomks247Async(
                                    (string)deviceElem.Attribute("ip"),
                                    (string)deviceElem.Attribute("name"),
                                    (string)deviceElem.Attribute("id"),
                                    (bool)deviceElem.Attribute("autoconnect")));
            var mks247s = await Task.WhenAll(getmks247Task);

CreateAndConnectTomks247Async方法定义如下:

private async Task<mks247Device> CreateAndConnectTomks247Async(string host, string name, string id, bool autoconnect = true)
    {
        mks247Device dev = new mks247Device(host, name, id);

        if (autoconnect)
        {
            if (await dev.ConnectAsync())
                dev.BeginPolling();
        }

        return dev;
    }

到目前为止一切都很好,问题出现了:如何将校准校准到校准对象列表中?

我正在尝试使用此代码的各种变体:

select CreateAndConnectTomks247Async(...)
{ // HERE COMES THE ERROR ALREADY - THIS BRACKET IS NOT ACCEPTED ANYMORE
    Calibrations = (from calbrationElem in deviceElem.Descendants("calibration")
    select new Calibration()
    {
        a = calbrationElem.Attribute("a").Value,
        /* and so on */ 
    }).ToList<Calibration>(); // Actually, I'd like to have it in an ObservableCollection in the end, but that is a minor thing...
}

我很感激任何帮助才能实现目标......

1 个答案:

答案 0 :(得分:0)

您需要做的是使用anoynmous对象来选择您需要的东西:

var getmks247Task = (
     from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device")
     where (string)deviceElem.Attribute("type") == "mks247"
     select new // => see the new keyword for the object declaration
     {
        Tomks247s = CreateAndConnectTomks247Async(/* your code */),
        Calibrations = deviceElem.Descendants("calibration")...
     };

var mks247s = await Task.WhenAll(getmks247Task.Select(x => x.Tomks247s).ToArray());