LINQ IEnumerable的序列化结果 [英] Serializing result of a LINQ IEnumerable

查看:79
本文介绍了LINQ IEnumerable的序列化结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的值类型:

I have a simple value type:

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

您会注意到的

是可序列化的.然后,我列出了这些清单:

which as you'll note is serializable. Then I have a list of these:

static private List<TimerInstance> _Timers = new List<TimerInstance>();

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

and a LINQ method to eliminate the bottom 5% and top 5% of timers from the list:

// 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%的情况:

I then am trying to Seralize to XML the result of this enumeration, i.e. serialize just the values of the timers in the middle 90%, eliminating the top and bottom 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());
}

问题是当执行此代码时,我得到了:

The problem is that when this code executes, I get this:

类型的第一次机会异常 发生"System.Runtime.Serialization.SerializationException" mscorlib.dll Microsoft.WindowsAzure.ServiceRuntime严重:1:未处理的异常: System.Runtime.Serialization.SerializationException:类型'System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance, TracePerfWorker,版本= 1.0.0.0,文化=中性, 程序集'System.Core,Version = 4.0.0.0中的PublicKeyToken = null]]', 文化=中性,PublicKeyToken = b77a5c561934e089'未标记为 可序列化. 在System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 类型) 在System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type 类型,StreamingContext上下文) 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj,ISurrogateSelector surrogateSelector,StreamingContext上下文, SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器, ObjectWriter objectWriter,SerializationBinder绑定程序) 在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj,ISurrogateSelector surrogateSelector,StreamingContext上下文, SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器, ObjectWriter objectWriter,SerializationBinder绑定程序) 在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object 图,Header [] inHeaders,__ BinaryWriter serWriter,布尔值fCheck) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,对象图,Header []标头,布尔值fCheck) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,对象图) 在c:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.TraceTimer.SerializeTimersToStream(Stream) 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ TraceTimer.cs:第88行 在c:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.SerializeTimersToBlob(String strTimerGroupName) 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:line 192 在c:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.DoWorkNoTrace() 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:line 153 在c:\ Users \ Mike \ Documents \ Visual Studio中的TracePerfWorker.WorkerRole.Run() 2010 \ Projects \ AzureTracePerfTest \ TracePerfWorker \ WorkerRole.cs:line 77 在Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRoleInternal() 在Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole() 在Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__1() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContext executeContext,ContextCallback回调,对象状态,布尔值 ignoreSyncCtx) 在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态) 在System.Threading.ThreadHelper.ThreadStart()

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')本身未标记为可序列化的

I think I get what this is telling me - the implicit class that the enumerator has apparently generated ('System.Linq.Enumerable+d__3a`1[[TracePerfWorker.TraceTimer+TimerInstance, TracePerfWorker') is not itself marked as serializable.

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

But this seems like a really common situation, where I'm taking a serializable value type (TimerInstance), and just building a LINQ query over a list of these values, i.e. the enumerator is just returning TimerInstance values - how do I then convince it that what the enumerator is returning is just a list of TimerInstance values, which are serializable?

推荐答案

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

How about using ToList to get a list of items before you call serialize? Your method will need to be changed to return a List<TimerInstance> instead of IEnumerable<TimerInstance>

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

这篇关于LINQ IEnumerable的序列化结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆