J'ai un type de valeur simple:résultat sérialisation d'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);
}
}
qui, comme vous remarquerez est sérialisable. Ensuite, j'ai une liste de ces derniers:
static private List<TimerInstance> _Timers = new List<TimerInstance>();
et une méthode LINQ pour éliminer les 5% et 5% des minuteries de la liste:
// 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);
}
Je suis alors en train de Seralize XML le résultat de cette énumération, à savoir sérialisation uniquement les valeurs des temporisateurs au milieu de 90%, ce qui élimine la partie supérieure et inférieure à 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());
}
le problème est que lorsque ce code exécute, je reçois ceci:
Une première possibilité exception de type 'System.Runtime.Serialization.SerializationException' se sont produits dans mscorlib.dll Microsoft.WindowsAzure.ServiceRuntime critique: 1: Exception non gérée: System.Runtime.Serialization.SerializationException: Type 'System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + MinuteurInstance, TracePerfWorker, Version = 1.0.0.0, Culture = neutre, PublicKeyToken = null]]' dans Assembly 'System.Core, Version = 4.0. 0,0, Culture = neutre, PublicKeyToken = b77a5c561934e089 'n'est pas marqué comme sérialisable. à System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (type RuntimeType ) à System.Runtime.Serialization.FormatterServices.GetSerializableMembers (type de type , contexte StreamingContext) à System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() à System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Object obj , ISurrogateSelector surrogateSelector, StreamingContext contexte, SerObjectInfoInit serObjectInfoInit, convertisseur IFormatterConverter, objectWriter objectWriter, liant SerializationBinder) à System.Runtime.Serialization. Formatters.Binary.WriteObjectInfo.Serialize (Object obj, ISurrogateSelector surrogateSelector, StreamingContext contexte, SerObjectInfoInit serObjectInfoInit, convertisseur IFormatterConverter, ObjectWriter objectWriter, liant SerializationBinder) à System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (graphique de l'objet , en-tête [] inHeaders, __BinaryWriter serWriter , Boolean fcheck) à System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (courant serializationStream, graphe d'objet, en-tête [] têtes, Boolean fcheck) à System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Flux serializationStream, Graphique d'objet) at TracePerfWorker.TraceTimer.SerializeTimersToStream (Streams) dans c: \ Users \ M ike \ Documents \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ TraceTimer.cs: ligne 88 à TracePerfWorker.WorkerRole.SerializeTimersToBlob (String strTimerGroupName) dans c: \ Users \ Mike \ Documents \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: ligne à TracePerfWorker.WorkerRole.DoWorkNoTrace() dans c: \ Utilisateurs \ Mike \ Documents \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: ligne à TracePerfWorker.WorkerRole.Run() dans c: \ Users \ Mike \ Documents \ Visual Studio 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs: ligne 77 à Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment .StartRoleInternal() à Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole() à Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__1() à System.Threading.ThreadHelper.ThreadStart_Context (état de l'objet) au système .Threading.ExecutionContext.Run (ExecutionContext executionContext, rappel ContextCallback, état de l'objet, booléen ignoreSyncCtx) à System.Threading.ExecutionContext.Run (ExecutionContext executio nContext, rappel ContextCallback, état d'objet) à System.Threading.ThreadHelper.ThreadStart()
Je pense que je reçois ce que cela me dit - la classe implicite que le recenseur a apparemment généré ('System.Linq. Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance, TracePerfWorker ') n'est pas lui-même marqué comme sérialisable. Mais cela semble être une situation très courante, où je prends une valeur sérialisable de type (TimerInstance), et de construire une requête LINQ sur une liste de ces valeurs, c'est-à-dire que l'énumérateur ne fait que retourner les valeurs de TimerInstance - comment puis-je alors convaincre que ce que l'énumérateur renvoie est juste une liste de valeurs de TimerInstance, qui sont sérialisables?
En fait, le type de retour de la méthode peut rester comme 'IEnumerable'. Il suffit d'ajouter le 'ToList'. –
Merci. C'est ce qu'il a fait. –
ToList() a également résolu mon problème: var timestamps = (à partir de t dans Enumerable.Range (1, chunk_samples) .Reverse() select now - t/sampling_rate) .ToList(); –