异步和匿名类型

时间:2013-02-15 01:32:14

标签: c# linq async-await

此方法:

private async Task readFileInfo(string folderId)

调用另一种方法:

importCount = await VM.importVehicles(myXDoc);

在这里定义:(注意:我将它从for循环更改为a for each,但我得到了类似的结果)。

public async Task<Int32> importVehicles(XDocument importXMLDocument)
{
    var Importedvehicles = from vehicle in importXMLDocument.Descendants("vehicle")
                           select new
                           {
                               VehicleName = vehicle.Element("VehicleName").Value,
                               VehicleYear = vehicle.Element("VehicleYear").Value,
                               Odometer = vehicle.Element("Odometer").Value,
                               LicensePlate = vehicle.Element("LicensePlate").Value,
                               OilWeight = vehicle.Element("OilWeight").Value,
                               OilQuantity = vehicle.Element("OilQuantity").Value,
                               OilFilterModelNumber = vehicle.Element("OilFilterModelNumber"),
                               AirFilterModelNumber = vehicle.Element("AirFilterModelNumber"),
                               OilChangedDate = vehicle.Element("OilChangedDate"),
                               OilChangedOdometer = vehicle.Element("OilChangedOdometer"),
                               NextOilChangeDate = vehicle.Element("NextOilChangeDate"),
                               NextOilChangeOdometer = vehicle.Element("NextOilChangeOdometer"),
                               SettingDistance = vehicle.Element("SettingDistance"),
                               SettingMonths = vehicle.Element("SettingMonths"),
                           };

    Int32 vehicleId;
    vehicleId = await getMaxVehicleId();
    try
    {

        foreach (var item in Importedvehicles)
        {
            vehicle myImportedVehicle = new vehicle();
            myImportedVehicle.VehicleId = vehicleId += 1;
            myImportedVehicle.ImagePath = "Assets/car2.png";
            myImportedVehicle.VehicleName = item.VehicleName;
            myImportedVehicle.VehicleModel = item.VehicleName;


            myImportedVehicle.VehicleYear = short.Parse(item.VehicleYear);
            myImportedVehicle.CurrentOdometer = Convert.ToInt32(item.Odometer);
            myImportedVehicle.LicensePlate = item.LicensePlate;
            myImportedVehicle.LastOilChangedDate = Convert.ToDateTime(item.OilChangedDate.Value.ToString()).ToString("d");
            myImportedVehicle.LastOilChangedOdometer = (Int32)item.OilChangedOdometer;
            myImportedVehicle.ReminderDistance = (Int32)item.SettingDistance;
            myImportedVehicle.ReminderMonths = (Int32)item.SettingMonths;

            vehicleInformation myImportVI = new vehicleInformation();
            myImportVI.OilWeight = item.OilWeight;
            myImportVI.OilAmount = item.OilQuantity;
            myImportVI.OilFilterNumber = item.OilFilterModelNumber.Value.ToString();
            myImportVI.AirFilterNumber = item.AirFilterModelNumber.Value.ToString();

            myImportedVehicle.vehicleInfo = myImportVI;
            m_vehicles.Add(myImportedVehicle);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
    }

        await SaveList();
        return Importedvehicles.Count();
    }

我收到了一个错误:

  

对象引用未设置为对象的实例。

当我单步执行时,iVehicle会突出显示,但随后会直接转到for语句。然后它看起来错误,因为它还没有得到iVehicle的结果。

2 个答案:

答案 0 :(得分:1)

这不是100%回答你的问题,但它应该给你一个良好的开端。

调试器在声明for...loop之后直接跳转到iVehicle的原因是因为在声明它时查询没有被执行。因此,iVehicle在那一点上不是匿名类型的集合。

当您致电.Count()时,正在执行查询,并且iVehicle正在尝试转换为正确的匿名类型集合。但是,由于查询中的某些内容(在您致电.Count()后正在执行)是null,因此您收到了NullReferenceException

首先应验证importXMLDocumentDescendants()调用的返回值是否均为空。

希望无论如何都有帮助。

修改

现在你已经给出了一个完整的例子,你有很多可能是null的地方。

每次使用时:

vehicle.Element("SomeElementNameHere")

这可能是null。然后,您在.Value对象上调用null属性。

你需要确保每个元素都在那里。隔离每个案例,并确定哪个是null

答案 1 :(得分:1)

尝试编写如下代码:

var query =
    from vehicle in importXMLDocument.Descendants("vehicle")
    select new { ... };

var  iVehicle = query.ToArray();

for (var i = 0; i <= iVehicle.Count(); i++)
{
    ...
}

您需要强制对查询进行评估。这就是.ToArray正在做的事情。查询本身只是查询的定义,而不是结果。