Сериализация результата 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 к 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());
}

Проблема состоит в том, что, когда этот код выполняется, я получаю это:

Первое случайное исключение типа 'Система. Время выполнения. Сериализация. SerializationException' произошел в mscorlib.dll Microsoft. WindowsAzure. Очень важный ServiceRuntime: 1: Необработанное исключение: Система. Время выполнения. Сериализация. SerializationException: Введите 'Систему. Linq. Enumerable+d __ 3a '1 [[TracePerfWorker. TraceTimer+TimerInstance, TracePerfWorker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' в блоке 'Система. Ядро, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' не отмечены как сериализуемые. в System. Время выполнения. Сериализация. FormatterServices. InternalGetSerializableMembers (тип RuntimeType) в System. Время выполнения. Сериализация. FormatterServices. GetSerializableMembers (Вводят тип, контекст StreamingContext) в System. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. WriteObjectInfo. InitMemberInfo () в Системе. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. WriteObjectInfo. InitSerialize (Возражают obj, ISurrogateSelector surrogateSelector, контексту StreamingContext, SerObjectInfoInit serObjectInfoInit, преобразователю IFormatterConverter, ObjectWriter objectWriter, редактору связей SerializationBinder) в System. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. WriteObjectInfo. Сериализируйте (Возразите obj, ISurrogateSelector surrogateSelector, контексту StreamingContext, SerObjectInfoInit serObjectInfoInit, преобразователю IFormatterConverter, ObjectWriter objectWriter, редактору связей SerializationBinder) в System. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. ObjectWriter. Сериализируйте (Граф объектов, Заголовок [] inHeaders, __ BinaryWriter serWriter, булевская переменная fCheck) в System. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. BinaryFormatter. Сериализируйте (Поток serializationStream, Граф объектов, Заголовок [] заголовки, булевская переменная fCheck) в System. Время выполнения. Сериализация. Средства форматирования. Двоичный файл. BinaryFormatter. Сериализируйте (Поток serializationStream, Граф объектов) в TracePerfWorker. TraceTimer. SerializeTimersToStream (Поток s) в c:\Users\Mike\Documents\Visual Studio 2010\Projects\AzureTracePerfTest\TracePerfWorker\TraceTimer.cs:line 88 в TracePerfWorker. WorkerRole. SerializeTimersToBlob (Представляют strTimerGroupName в виде строки) в c:\Users\Mike\Documents\Visual Studio 2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line 192 в TracePerfWorker. WorkerRole. DoWorkNoTrace () в c:\Users\Mike\Documents\Visual Studio 2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line 153 в TracePerfWorker. WorkerRole. Выполненный () в c:\Users\Mike\Documents\Visual Studio 2010\Projects\AzureTracePerfTest\TracePerfWorker\WorkerRole.cs:line 77 в Microsoft. WindowsAzure. ServiceRuntime. RoleEnvironment. StartRoleInternal () в Microsoft. WindowsAzure. ServiceRuntime. RoleEnvironment. StartRole () в Microsoft. WindowsAzure. ServiceRuntime. Реализация. Загрузчик. RoleRuntimeBridge.b __ 1 () в Системе. Поточная обработка. ThreadHelper. ThreadStart_Context (Объектное состояние) в System. Поточная обработка. ExecutionContext. Выполненный (ExecutionContext executionContext, обратный вызов ContextCallback, Объектное состояние, булевская переменная ignoreSyncCtx) в System. Поточная обработка. ExecutionContext. Выполненный (ExecutionContext executionContext, обратный вызов ContextCallback, Объектное состояние) в System. Поточная обработка. ThreadHelper. ThreadStart ()

Я думаю, что получаю то, что это говорит мне - неявный класс, что перечислитель, по-видимому, генерировал ('Система. Linq. Enumerable+d __ 3a '1 [[TracePerfWorker. TraceTimer+TimerInstance, TracePerfWorker'), самостоятельно не отмечен как сериализуемый.

Но это походит на действительно общую ситуацию, где я беру сериализуемый тип значения (TimerInstance) и просто создаю запрос LINQ по списку этих значений, т.е. перечислитель просто возвращает значения TimerInstance - как я затем убеждаю его, который, что возвращает перечислитель, просто список значений TimerInstance, которые являются сериализуемыми?

14
задан Galma88 16 October 2015 в 15:56
поделиться

1 ответ

Как насчет использования ToList для получения списка элементов перед вызовом serialize? Ваш метод необходимо будет изменить, чтобы он возвращал List вместо IEnumerable

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

16
ответ дан 1 December 2019 в 13:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: