序列化LINQ IEnumerable的结果

Mik*_*lly 14 c# 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

你会注意到它是可序列化的.然后我列出了这些:

static private List<TimerInstance> _Timers = new List<TimerInstance>();
Run Code Online (Sandbox Code Playgroud)

和一个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);
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试将此枚举的结果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());
}
Run Code Online (Sandbox Code Playgroud)

问题是当这段代码执行时,我得到了这个:

mscorlib.dll中发生类型为"System.Runtime.Serialization.SerializationException"的第一次机会异常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,PublicKeyToken = null]]'在Assembly'System.Core,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'不是标记为可序列化.在System.Runtime.Serialization.Serialization.Formatters.Binary的System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type,StreamingContext context)中的System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType类型).

我想我得到了这个告诉我的内容 - 枚举器显然生成的隐式类('System.Linq.Enumerable + d__3a`1 [[TracePerfWorker.TraceTimer + TimerInstance,TracePerfWorker')本身并不标记为可序列化.

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

Raj*_*mal 16

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

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

  • 实际上,方法返回类型可以保持为`IEnumerable <TimerInstance>`.只需添加`ToList`就足够了. (4认同)