[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); } }
你会注意到的是可序列化的.然后我有一个列表:
static private List<TimerInstance> _Timers = new List<TimerInstance>();
和一个LINQ方法来消除列表中的5%和5%的定时器:
// 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); }
然后,我试图将这个枚举的结果列为XML,即仅将90%的定时器的值序列化,从而消除了顶部和底部的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()); }
问题是当这个代码执行时,我得到:
A first chance exception of type
‘System.Runtime.Serialization.SerializationException’ occurred in
mscorlib.dll
Microsoft.WindowsAzure.ServiceRuntime Critical: 1 : Unhandled Exception:
System.Runtime.Serialization.SerializationException: Type ‘System.Linq.Enumerable+d__3a`1[[TracePerfWorker.TraceTimer+TimerInstance,
TracePerfWorker,Version=1.0.0.0,Culture=neutral,
PublicKeyToken=null]]’ in Assembly ‘System.Core,Version=4.0.0.0,
Culture=neutral,PublicKeyToken=b77a5c561934e089’ is not marked as
serializable.
at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType
type)
at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type
type,StreamingContext context)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object
obj,ISurrogateSelector surrogateSelector,StreamingContext context,
SerObjectInfoInit serObjectInfoInit,IFormatterConverter converter,
ObjectWriter objectWriter,SerializationBinder binder)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object
obj,SerializationBinder binder)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object
graph,Header[] inHeaders,__BinaryWriter serWriter,Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream
serializationStream,Object graph,Header[] headers,Object graph)
at TracePerfWorker.TraceTimer.SerializeTimersToStream(Stream s) in c:\Users\Mike\Documents\Visual Studio
2010\Projects\AzureTracePerfTest\TracePerfWorker\TraceTimer.cs:line 88
at TracePerfWorker.WorkerRole.SerializeTimersToBlob(String strTimerGroupName) in c:\Users\Mike\Documents\Visual Studio
2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line
192
at TracePerfWorker.WorkerRole.DoWorkNoTrace() in c:\Users\Mike\Documents\Visual Studio
2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line
153
at TracePerfWorker.WorkerRole.Run() in c:\Users\Mike\Documents\Visual Studio
2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line 77
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRoleInternal()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole()
at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__1()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean
ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state)
at System.Threading.ThreadHelper.ThreadStart()
我想我得到这是告诉我 – 枚举器显然生成的隐式类(‘System.Linq.Enumerable d__3a`1 [[TracePerfWorker.TraceTimer TimerInstance,TracePerfWorker’)本身不被标记为可序列化.
但这似乎是一个非常常见的情况,我正在采取可序列化的价值类型
(TimerInstance),并且只是在这些值的列表上构建一个LINQ查询,即枚举器只是返回TimerInstance值 – 那么如何才能说服枚举器返回的只是一个TimerInstance值列表,它们是可序列化的?