Ho un semplice tipo di valore:Serializzazione risultato di un LINQ IEnumerable
[Serializable]
private struct TimerInstance
{
public TimerInstance(string str, long nTicks)
{
_name = str;
_ticks = nTicks;
}
private readonly string _name;
private readonly long _ticks;
public string Name { get { return _name; } }
public long Ticks { get { return _ticks; } }
public override string ToString()
{
return string.Format("{0,20}: {1,10:N}", Name, Ticks);
}
}
che, come si noterà è serializzabile. Poi ho un elenco di questi:
static private List<TimerInstance> _Timers = new List<TimerInstance>();
e un metodo LINQ per eliminare la parte inferiore del 5% e il top 5% di timer dalla lista:
// Return items that should be persisted. By convention, we are eliminating the "outlier"
// values which I've defined as the top and bottom 5% of timer values.
private static IEnumerable<TimerInstance> ItemsToPersist()
{
// Eliminate top and bottom 5% of timers from the enumeration. Figure out how many items
// to skip on both ends.
int iFivePercentOfTimers = _Timers.Count/20;
int iNinetyPercentOfTimers = _Timers.Count - iFivePercentOfTimers * 2;
return (from x in _Timers
orderby x.Ticks descending
select x).Skip(iFivePercentOfTimers).Take(iNinetyPercentOfTimers);
}
Ho quindi sto cercando di Seralize in XML il risultato di questa enumerazione, cioè serializzare solo i valori dei temporizzatori del mezzo 90%, eliminando la parte superiore e inferiore 5%:
// Serialize the timer list as XML to a stream - for storing in an Azure Blob
public static void SerializeTimersToStream(Stream s)
{
BinaryFormatter f = new BinaryFormatter();
f.Serialize(s, ItemsToPersist());
}
il problema è che quando questo codice viene eseguito, ottengo questo:
Una prima eccezione di possibilità di tipo 'System.Runtime.Serialization.SerializationException' verificato in mscorlib.dll Microsoft.WindowsAzure.ServiceRuntime Critici: 1: eccezione non gestita: System.Runtime.Serialization.SerializationException: Digitare 'System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance, TracePerfWorker, Versione = 1.0.0.0, Cultura = neutra, PublicKeyToken = null]]' in Assembly 'System.Core, Versione = 4.0. 0.0, Culture = neutro, PublicKeyToken = b77a5c561934e089 'non è contrassegnato come serializzabile . a System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (RuntimeType tipo) a System.Runtime.Serialization.FormatterServices.GetSerializableMembers (Tipo tipo, contesto StreamingContext) a System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() a System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Object obj , ISurrogateSelector surrogateSelector, contesto StreamingContext, serObjectInfoInit serObjectInfoInit, convertitore IFormatterConverter, ObjectWriter objectWriter, SerializationBinder legante) a System.Runtime.Serialization. Formatters.Binary.WriteObjectInfo.Serialize (oggetto obj, ISurrogateSelector surrogateSelector, contesto StreamingContext, SerObjectInfoInit serObjectInfoInit, convertitore IFormatterConverter, ObjectWriter objectWriter, SerializationBinder legante) a System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (Object grafico, Header [] inHeaders, __BinaryWriter serWriter , booleano FVerificare) a System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (stream serializationStream, oggetto grafico, intestazioni Header [], Boolean FVerificare) a System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationStream, Object graph) su TracePerfWorker.TraceTimer.SerializeTimersToStream (Stream s) in c: \ Users \ M ike \ Documenti \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ TraceTimer.cs: linea 88 a TracePerfWorker.WorkerRole.SerializeTimersToBlob (String strTimerGroupName) in C: \ Users \ Mike \ Documenti \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: riga in TracePerfWorker.WorkerRole.DoWorkNoTrace() in c: \ Users \ Mike \ Documents \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: Linea a TracePerfWorker.WorkerRole.Run() in C: \ Users \ Mike \ Documenti \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: linea 77 a Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment .StartRoleInternal() a Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole() a Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__1() a System.Threading.ThreadHelper.ThreadStart_Context (stato oggetto) presso System .Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) in System.Threading.ExecutionContext.Run (Esegui ExecutionContext nContext, ContextCallback callback, Object state) a System.Threading.ThreadHelper.ThreadStart()
penso ottengo ciò che questo mi sta dicendo - la classe implicita che l'enumeratore ha apparentemente generato ('System.Linq. Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance, TracePerfWorker ') non è contrassegnato come serializzabile.
Ma questa sembra una situazione molto comune, dove sto prendendo un tipo di valore serializable (TimerInstance), e solo la costruzione di una query LINQ su un elenco di questi valori, vale a dire l'enumeratore è solo la restituzione di valori TimerInstance - come faccio quindi a convincerlo che ciò che l'enumeratore sta restituendo è solo un elenco di valori di TimerInstance, che sono serializzabili?
In realtà, il tipo di metodo di ritorno può rimanere come 'IEnumerable'. Basta aggiungere il 'ToList' è sufficiente. –
Grazie. Questo è stato. –
ToList() ha risolto anche il mio problema: var timestamp = (da t in Enumerable.Range (1, chunk_samples) .Reverse() selezionare ora - t/sampling_rate) .ToList(); –