循环遍历从方法返回的列表,直到该方法没有给我记录

时间:2013-06-25 15:43:13

标签: c#

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;
  }
}

5 个答案:

答案 0 :(得分:3)

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

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

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

  2. 如果您能够更改Reading.GetUnProcessReadings()中的代码,则可以选择使用yield。因此,您将避免不必要的ToList(..)调用,因此每次都会生成新List<T>代,并且完全避免while循环,只需使用foreach

答案 1 :(得分:2)

而不是DoWhile中的所有内容,为什么不在foreach循环的末尾添加一个基本上读取的if语句

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

答案 2 :(得分:0)

如果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
    }
}

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

比这更远,你确定你需要一次性保存所有的GPS读数吗?有没有办法一次保存一个?然后你可以有像

这样的东西
client.SaveSingleGpsReading (globalSetting.TokenId, globalSetting.SourceId, gpsreading);

在循环内部。

我最重要的是你似乎在考虑获取一些东西,将它按摩到不同的集合类型,在整个集合上运行一个进程,以及按摩 进入不同的集合类型......当有效的事情是拉动输入,用它做你需要的东西,把它发送到输出,然后重复。

当您不需要时,不要保留巨大的数据缓冲区。那么如何管理所有馆藏的问题就没有用了。

答案 3 :(得分:0)

这是一种通过事件做的方式。

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; }
    }
}
}

答案 4 :(得分:0)

而不是

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;
        }