微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

然后,我试图将这个枚举的结果列为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,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,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,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

原文地址:https://www.jb51.cc/csharp/94997.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐