循环遍历从一个方法返回的列表,直到该方法没有给我任何记录为止

本文关键字:方法 记录 任何 列表 遍历 循环 返回 一个 | 更新日期: 2023-09-27 18:19:47

Reading.GetUnProcessReadings().ToList();一次返回20个事务。我需要循环它,直到它根本不返回任何交易。

我有以下代码,我认为它不是有效的:

    IEnumerable<SSS.ServicesConfig.data.Reading> readings = Reading.GetUnProcessReadings().ToList();;
    var gpsreadings = new List<TruckGpsReading>();
    do
    {
      gpsreadings = new List<TruckGpsReading>();
      if (readings.Count() > 0)
      {
        foreach (var reading in readings)
        {
          Logging.Log("Starting ProcessGpsFile.ProcessReading 3", "ProcessReading", Apps.RemoteTruckService);
          var gpsreading = new TruckGpsReading();
          gpsreading.DateTimeOfReading = reading.DateTimeOfReading;
          gpsreading.Direction = reading.Direction;
          gpsreading.DriverNumber = CurrentIniSettings.DriverNumber;
          gpsreading.Latitude = (float)reading.Latitude;
          gpsreading.Longitude = (float)reading.Longitude;
          gpsreading.Speed = reading.Speed;
          gpsreading.TruckNumber = CurrentIniSettings.TruckNumber;
          gpsreadings.Add(gpsreading);
        }
        var response = client.SaveGpsReadings(globalSetting.TokenId, globalSetting.SourceId, gpsreadings.ToArray());
        if (response != "true")
        {
          Logging.Log("ProcessGpsFile.ProcessReading: " + response, "ProcessReading", Apps.RemoteTruckService);
        }
        else
        {
          Logging.Log("ProcessGpsFile.ProcessReading: Reading.DeleteGpsReadings(readings)", "ProcessReading", Apps.RemoteTruckService);
          SSS.ServicesConfig.data.Reading.DeleteGpsReadings(readings);    
        }
      }
      readings = Reading.GetUnProcessReadings().ToList();
    } while (readings.Count() > 0);

有更好的方法吗?

**编辑**

public static IEnumerable<Reading> GetUnProcessReadings()
{
  try
  {
    using (var context = new SuburbanEntities())
    {
      return (from r in context.Readings
             where r.IsPublished == false
             select r).Take(10).ToList();
    }
  }
  catch (Exception ex)
  {
    Logging.Log("An error occurred.", "GetPpsSetting", Apps.ServicesConfig, ex);
    return null;
  }
}

循环遍历从一个方法返回的列表,直到该方法没有给我任何记录为止

从提供的代码中很难找到最佳解决方案,但。。。

不要像现在这样看到代码的严重问题,除了几个建议:

  1. 使用while (readings.Count() > 0) {},而不是do/while,因为在第一次请求时,可能没有要解析的读数。

  2. 如果您能够更改Reading.GetUnProcessReadings()内部的代码,那么这可能是一个使用yield进行查看的选项。所以你会避免不必要的ToList(..)调用,所以每次都会生成新的List<T>,并且会完全避免while循环,只会使用foreach

与其所有内容都在DoWhile中,为什么不在foreach循环的末尾放一个if语句呢

if(readings.count() <=0)
{
     break;
}

如果Reading.GetUnProcessReadings()给了你一些可迭代的东西,它可能会这样做,因为.ToList()通常是你想创建IEnumerable时要做的事情,为什么不迭代它呢?

或多或少像这样的东西:

public void MyBigWrapperMethod()
{
    var gpsreadings = new List<TruckGpsReading>();
    foreach (var reading in Reading.GetUnProcessReadings())
    {
        Logging.Log("Starting ProcessGpsFile.ProcessReading 3", "ProcessReading", Apps.RemoteTruckService);
        var gpsreading = new TruckGpsReading();
        gpsreading.DateTimeOfReading = reading.DateTimeOfReading;
        gpsreading.Direction = reading.Direction;
        gpsreading.DriverNumber = CurrentIniSettings.DriverNumber;
        gpsreading.Latitude = (float)reading.Latitude;
        gpsreading.Longitude = (float)reading.Longitude;
        gpsreading.Speed = reading.Speed;
        gpsreading.TruckNumber = CurrentIniSettings.TruckNumber;
        gpsreadings.Add(gpsreading);
    }
    var response = client.SaveGpsReadings(globalSetting.TokenId,
     globalSetting.SourceId, gpsreadings.ToArray());
    if (response == "true")
    {
        // do stuff if it works
    }
    else
    {
        // do stuff if it doesn't work
    }
}

此外,client对象的SaveGpsReadings方法很有可能不需要将最后一个参数转换为Array形式。如果可以的话,可以考虑将其重写为采用TruckGpsReading对象集合的方法。

更进一步,你确定你需要像那样一批一批地保存所有GPS读数吗?有没有办法一次救一个?然后你可以有类似的东西

client.SaveSingleGpsReading (globalSetting.TokenId, globalSetting.SourceId, gpsreading);

就在循环内。

我想说的主要一点是,你似乎在思考如何获得一个东西的集合,将其按摩成不同的集合类型,对整个集合运行一个过程,并将的输出按摩成不同的集合类型。。。当有效的方法是提取一个输入,用它做你需要做的事情,把它发送到输出,然后重复。

在不必要的时候不要保留巨大的数据缓冲区。然后,如何管理所有集合的问题就变得毫无意义了。

这里有一种完成事件的方法。

using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace BackgroundWorkerExample
{
public class Program
{
    private event EventHandler<EventArgs<List<SSS.ServicesConfig.data.Reading>>> ReadingAvailable;
    protected virtual void OnReadingAvailable(List<SSS.ServicesConfig.data.Reading> list)
    {
        EventHandler<EventArgs<List<SSS.ServicesConfig.data.Reading>>> handler = ReadingAvailable;
        if (handler != null)
        {
            handler(this, new EventArgs<List<SSS.ServicesConfig.data.Reading>> (list) );
        }
    }
    private BackgroundWorker bw = new BackgroundWorker();
    void Main(string[] args)
    {
        this.ReadingAvailable +=Program_ReadingAvailable;
        bw.DoWork +=bw_DoWork;
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }
    private void Program_ReadingAvailable(object sender, EventArgs<List<SSS.ServicesConfig.data.Reading>> e)
    {
        List<SSS.ServicesConfig.data.Reading> list = e.Value;
        // for each item in the list do something.
        foreach (var reading in list)
        {
            Logging.Log("Starting ProcessGpsFile.ProcessReading 3", "ProcessReading", Apps.RemoteTruckService);
            var gpsreading = new TruckGpsReading();
            gpsreading.DateTimeOfReading = reading.DateTimeOfReading;
            gpsreading.Direction = reading.Direction;
            gpsreading.DriverNumber = CurrentIniSettings.DriverNumber;
            gpsreading.Latitude = (float)reading.Latitude;
            gpsreading.Longitude = (float)reading.Longitude;
            gpsreading.Speed = reading.Speed;
            gpsreading.TruckNumber = CurrentIniSettings.TruckNumber;
            gpsreadings.Add(gpsreading);
        }
        var response = client.SaveGpsReadings(globalSetting.TokenId, globalSetting.SourceId, gpsreadings.ToArray());
        if (response != "true")
        {
            Logging.Log("ProcessGpsFile.ProcessReading: " + response, "ProcessReading", Apps.RemoteTruckService);
        }
        else
        {
            Logging.Log("ProcessGpsFile.ProcessReading: Reading.DeleteGpsReadings(readings)", "ProcessReading", Apps.RemoteTruckService);
            SSS.ServicesConfig.data.Reading.DeleteGpsReadings(readings);
        }
    }
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        // if there is something to read
        IEnumerable<SSS.ServicesConfig.data.Reading> readings = Reading.GetUnProcessReadings().ToList();
        if (readings.Count() > 0)
        {
            OnReadingAvailable(readings);
        }
    }
}
public class EventArgs<T> : EventArgs
{
    private readonly T m_value;
    protected EventArgs()
        : base()
    {
        m_value = default(T);
    }
    public EventArgs(T value)
    {
        m_value = value;
    }
    public T Value
    {
        get { return m_value; }
    }
}
}

而不是

IEnumerable<SSS.ServicesConfig.data.Reading> readings

做。。。

List<SSS.ServicesConfig.data.Reading> readings

因为你申报的是List而不是

var gpsreadings = new List<TruckGpsReading>();

明确地做…

List<TruckGpsReading> gpsreadings =

然后在你做工作的方法里做这个

List<SSS.ServicesConfig.data.Reading> readings = Reading.GetUnProcessReadings().ToList();
List<TruckGpsReading> gpsreadings = RecursionMethod(readings, new List<TruckGpsReading>());

然后创建RecursionMethod。。。。

private List<TruckGpsReading> RecursionMethod(List<SSS.ServicesConfig.data.Reading> first,List<TruckGpsReading> second)
        {
            if (first.Count == 0)
            {
            }
            else
            {
                foreach (var item in first)
                {
                    //do the work of adding that you where doing..
                    Logging.Log("Starting ProcessGpsFile.ProcessReading 3", "ProcessReading", Apps.RemoteTruckService);
                    var gpsreading = new TruckGpsReading();
                    gpsreading.DateTimeOfReading = reading.DateTimeOfReading;
                    gpsreading.Direction = reading.Direction;
                    gpsreading.DriverNumber = CurrentIniSettings.DriverNumber;
                    gpsreading.Latitude = (float)reading.Latitude;
                    gpsreading.Longitude = (float)reading.Longitude;
                    gpsreading.Speed = reading.Speed;
                    gpsreading.TruckNumber = CurrentIniSettings.TruckNumber;
                    second.Add(gpsreading);
                    first.Remove(item);
                    //you need to break or you will get an invalidoperation exception
                    break;
                }
                RecursionMethod(first,second);
            }
            return second;
        }