循环遍历从一个方法返回的列表,直到该方法没有给我任何记录为止
本文关键字:方法 记录 任何 列表 遍历 循环 返回 一个 | 更新日期: 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;
}
}
从提供的代码中很难找到最佳解决方案,但。。。
不要像现在这样看到代码的严重问题,除了几个建议:
-
使用
while (readings.Count() > 0) {}
,而不是do/while
,因为在第一次请求时,可能没有要解析的读数。 -
如果您能够更改
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;
}