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;
}
}
答案 0 :(得分:3)
从提供的代码中很难找到最佳解决方案,但是......
除了几个建议之外,不要像现在这样看到严重的代码问题:
使用while (readings.Count() > 0) {}
,而不是do/while
,因为在第一次请求时可能没有要解析的读数。
如果您能够更改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;
}