序列化LINQ IEnumerable的结果

时间:2010-07-17 05:22:25

标签: 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);
        }
    }

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

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值列表?

1 个答案:

答案 0 :(得分:16)

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

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