1

一次返回20Reading.GetUnProcessReadings().ToList();笔交易。我需要遍历它,直到它根本没有返回任何交易。

我有以下代码,但我认为它效率不高:

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

5 回答 5

3

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

没有看到代码有严重的问题,就像现在一样,除了一些建议:

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

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

于 2013-06-25T15:50:00.143 回答
2

与其将所有内容都放在 DoWhile 中,不如在 foreach 循环的末尾放置一个 if 语句,该语句基本上读取

if(readings.count() <=0)
{
     break;
}
于 2013-06-25T15:51:29.717 回答
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;
        }
于 2013-06-25T16:41:07.210 回答
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);

就在循环内。

我要说的主要问题是,您似乎在考虑获取一个东西的集合,将其按摩到不同的集合类型中,在整个集合上运行一个进程,然后将其输出按摩另一个集合中类型...当有效的做法是提取输入时,用它做你需要做的事情,将它发送到输出,然后重复。

不必要时不要保留巨大的数据缓冲区。那么如何管理所有收藏的问题就变得没有意义了。

于 2013-06-25T16:23:41.187 回答
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; }
    }
}
}
于 2013-06-25T16:36:26.703 回答