gpt4 book ai didi

c# - LINQ IEnumerable 的序列化结果

转载 作者:可可西里 更新时间:2023-11-01 07:56:15 27 4
gpt4 key购买 nike

我有一个简单的值类型:

    [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>();

以及从列表中删除底部 5% 和顶部 5% 计时器的 LINQ 方法:

// 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, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, 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, Boolean fCheck) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, 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, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

我想我明白了这是在告诉我什么——枚举器显然生成的隐式类 ('System.Linq.Enumerable+d__3a`1[[TracePerfWorker.TraceTimer+TimerInstance, TracePerfWorker') 本身并未标记为可序列化.

但这似乎是一种非常常见的情况,我采用可序列化的值类型(TimerInstance),并且只是在这些值的列表上构建 LINQ 查询,即枚举器只是返回 TimerInstance 值 - 然后我如何说服它枚举器返回的只是一个 TimerInstance 值列表,这些值是可序列化的?

最佳答案

在调用序列化之前使用 ToList 获取项目列表怎么样?您的方法需要更改以返回 List<TimerInstance>而不是 IEnumerable<TimerInstance>

http://msdn.microsoft.com/en-us/library/bb342261.aspx

关于c# - LINQ IEnumerable 的序列化结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3270367/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com