我有一个简单的值类型:
[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);
}
然后我尝试将此枚举的结果Seralize to 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());
}
问题是当这段代码执行时,我得到了这个:
类型的第一次机会异常 发生'System.Runtime.Serialization.SerializationException' mscorlib.dll中 Microsoft.WindowsAzure.ServiceRuntime严重:1:未处理的异常: System.Runtime.Serialization.SerializationException:输入'System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance, TracePerfWorker,Version = 1.0.0.0,Culture = neutral, 在Assembly'System.Core中,PublicKeyToken = null]]',版本= 4.0.0.0, Culture = neutral,PublicKeyToken = b77a5c561934e089'未标记为 序列化。 在System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 类型) 在System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type,StreamingContext context) 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj,ISurrogateSelector surrogateSelector,StreamingContext context, SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器, ObjectWriter objectWriter,SerializationBinder binder) 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj,ISurrogateSelector surrogateSelector,StreamingContext context, SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器, ObjectWriter objectWriter,SerializationBinder binder) 在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph,Header [] inHeaders,__BinaryWriter serWriter,Boolean fCheck) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph,Header [] headers,Boolean fCheck) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph) atT:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.TraceTimer.SerializeTimersToStream(Stream s) 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ TraceTimer.cs:第88行 atT:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.SerializeTimersToBlob(String strTimerGroupName) 2010 \项目\ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:行 192 atT:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.DoWorkNoTrace() 2010 \项目\ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:行 153 atT:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.Run() 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:第77行 在Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRoleInternal() 在Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole() 在Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__1() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx) 在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态) 在System.Threading.ThreadHelper.ThreadStart()
我想我得到了这个告诉我的内容 - 枚举器显然生成的隐式类('System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance,TracePerfWorker')本身并未标记为可序列化
但这似乎是一种非常常见的情况,我采用的是可序列化的值类型 (TimerInstance),只是在这些值列表上构建一个LINQ查询,即枚举器只返回TimerInstance值 - 我怎么说服枚举器返回的只是一个可序列化的TimerInstance值列表?
答案 0 :(得分:16)
在调用serialize之前如何使用ToList获取项目列表?
您的方法需要更改为返回List<TimerInstance>
而不是IEnumerable<TimerInstance>