Runtime: Pregunta: Soporte de serialización a partir de .Net Core 1.0

Creado en 1 mar. 2016  ·  38Comentarios  ·  Fuente: dotnet/runtime

Hola a todos,
He oído hablar de la suspensión de la compatibilidad con la serialización en .Net Core 1.0, ya que no es viable para plataformas cruzadas. (Parafraseando de memoria) ¿Qué significa esto en términos prácticos? ¿Mis bases de código que usan los métodos Serialize y Deserialize de BinaryFormatter serán completamente obsoletas y tendré que convertir mi base de código para decir, protobuf-net? ¿O lo he entendido mal?
Gracias,
-Sam

area-Serialization question

Comentario más útil

¿Quiere que la gente realmente use .NET Core o es solo una pérdida de tiempo como Silverlight? Si desea que la gente realmente use .NET Core, hágalo funcionar. Si la gente necesita serialización, constrúyala, ¡sin comentarios negativos! Estas son las personas que realmente usan su producto y su opinión vale mucho más que la sabiduría colectiva de cada empleado de Microsoft. Verá que estas personas, a diferencia de Microsoft, en realidad están construyendo cosas de misión crítica en .NET y si quiere que .NET Core sea algo, debe dejar de romper su utilidad. Nadie le pidió que abandonara .NET para hacer una reescritura completa, podría haber portado el marco .NET completo con el tiempo. Ya habrías terminado.

Todos 38 comentarios

Hola @joshfree , si lamentablemente ese fue el documento que causó la confusión. Fuera de las sugerencias allí, JSON.NET realiza la serialización json, protobuf-net realiza la serialización binaria y datacontractserializer realiza la serialización xml. El problema con eso es si quiero hacer una serialización binaria. Si bien protobuf-net es una gran biblioteca, es limitada. Desde el repositorio de Protobuf-nets, los tipos admitidos son:
clases personalizadas que:
están marcados como contrato de datos
tener un constructor sin parámetros
para Silverlight: son públicos
muchas primitivas comunes, etc.
matrices de una dimensión: T []
Lista / IList
Diccionario / IDiccionario
cualquier tipo que implemente IEnumerable y tenga un método Add (T)
En el pasado esto ha estado bien, ya que el formato binario siempre ha estado ahí, pero ¿ya no va a ser así? ¿Cuál es la forma recomendada de serialización binaria de tipos no admitidos por protobuf-net? ¿Construirlo nosotros mismos?
Todavía soy bastante novato en todas estas tecnologías, por lo que es posible que me esté perdiendo el sentido de algo.

Además, ninguno de ellos puede serializar excepciones de manera confiable (y mantener todos los datos relevantes), según sea necesario, por ejemplo, en computación distribuida (Azure ...).

El punto

Hola @SamuelCox , como señaló la guía de migración @joshfree , nosotros (el equipo de serialización) no tenemos ningún plan para llevar el serializador binario a .NET Core. Sin la comunicación remota de .NET y el concepto de dominio de aplicación en .NET Core, el serializador binario es mucho menos útil. Tenga en cuenta otros serializadores en .NET Core como DataContractSerializer (DCS), DataContractJsonSerializer (DCJS) y XmlSerializer, que son y seguirán siendo compatibles con .NET Core. Por supuesto, también puede considerar los serializadores de terceros creados en .NET Core. Tal vez debería hacer la pregunta: ¿está buscando particularmente un serializador que tenga una carga útil serializada binaria (si es así, por qué) o simplemente busca un serializador que pueda serializar / deserializar los tipos que le interesan? Nos hemos esforzado mucho para admitir la serialización de la mayoría de los tipos .NET con DCS, DCJS y XmlSerializer. No dude en informarnos si tiene algún problema en particular que indique que estos serializadores no funcionan para usted.

@cdrnet y @ RichiCoder1 , gracias por sus comentarios. Había un problema abierto dotnet / coreclr # 2715 para la discusión de la serialización de la excepción. Agregue sus comentarios allí. Estoy de acuerdo en que es importante poder serializar excepciones en un sistema distribuido. Actualmente, sin ISerializable en .NET Core, simplemente no podemos serializar excepciones como lo hacemos en el marco .NET completo.

Hola @zhenlan , quizás debería haber mencionado originalmente, la razón principal por la que querría binaryformatter es (des) serializar excepciones y clases personalizadas que contienen excepciones.

El caso de uso principal son los sistemas distribuidos, serializando algún objeto en una matriz de bytes para que pueda enviarlo a través de tcp / ip. Me doy cuenta de que probablemente sea más común serializar el objeto a JSON a través de JSON.NET, por ejemplo, convertir esa cadena en una matriz de bytes, enviarla a través de tcp / ip e invertir todo el proceso una vez en el otro extremo. Pero eso tiene mucha más sobrecarga que solo serializar en una matriz de bytes y deserializar desde una matriz de bytes al objeto que desea.

Gracias @SamuelCox por la aclaración. Creo que ahora entiendo tu preocupación. La serialización binaria es un sistema cerrado. Le recomendaría que considere otras serializaciones basadas en estándares más abiertos, como Xml o JSON. Es posible que no lo necesite hoy, pero le brinda más flexibilidad en caso de que necesite admitir la serialización entre diferentes plataformas o con diferentes lenguajes de programación / scripts en el futuro. No estoy seguro de qué tan grandes serán sus datos, pero si el tamaño de la carga útil es realmente una preocupación, puede considerar la compresión de datos, que es una característica incorporada para muchos servidores hoy en día.

Pensaba más en la actuación que en otra cosa. Parece que se desperdician muchas operaciones en comparación con la serialización y deserialización directamente de objetos a binarios y viceversa. Creo que estoy feliz de cerrar esto ahora, ya que al menos recibí una aclaración. Sigo pensando que hay una brecha entre 4.6 y el núcleo 1.0 que se está abriendo aquí, pero entiendo por qué.

Un poco tarde para la conversación, pero aquí están mis dos centavos:

Creo que sería un error creer que la utilidad de BinaryFormatter se limita a la comunicación remota .NET y AppDomains. Lo que diferencia al (obsoleto) BinaryFormatter de sus contrapartes más recientes es su gran capacidad de serializar los objetos .NET más exóticos, incluidos cierres, subtipos y gráficos cíclicos. Ninguno de los otros serializadores enumerados en el hilo actual es capaz de hacer todo esto. No es una coincidencia que muchos marcos distribuidos de vanguardia, incluidos proyectos de Microsoft como Prajna y Mobius (también conocidos como SparkCLR), confíen en BinaryFormatter para funcionar. Esto no es exclusivo del mundo .NET: Spark usa el antiguo y lento serializador binario de Java para serializar cierres.

Hay otros serializadores (de formato no binario) que replican las capacidades de BinaryFormatter, incluida nuestra propia biblioteca FsPickler utilizada por el marco mbrace. Sin embargo, CoreCLR ha desaprobado muchas API clave, en la medida en que creo que trasladar la biblioteca a CoreCLR es un esfuerzo poco práctico.

Desde una perspectiva empresarial, sería fantástico ver que CoreCLR se convierta en un competidor multiplataforma viable para JVM en el dominio de la computación distribuida / big data. Esto no puede suceder sin que la plataforma ofrezca un soporte de serialización confiable para POCO y cierres (binarios o de otro tipo).

¿Quiere que la gente realmente use .NET Core o es solo una pérdida de tiempo como Silverlight? Si desea que la gente realmente use .NET Core, hágalo funcionar. Si la gente necesita serialización, constrúyala, ¡sin comentarios negativos! Estas son las personas que realmente usan su producto y su opinión vale mucho más que la sabiduría colectiva de cada empleado de Microsoft. Verá que estas personas, a diferencia de Microsoft, en realidad están construyendo cosas de misión crítica en .NET y si quiere que .NET Core sea algo, debe dejar de romper su utilidad. Nadie le pidió que abandonara .NET para hacer una reescritura completa, podría haber portado el marco .NET completo con el tiempo. Ya habrías terminado.

fwiw, CSLA .NET se basa en la serialización de fidelidad total porque se basa en el concepto de objetos móviles.

Cuando apareció Silverlight y no tenía BinaryFormatter o NetDataContractSerializer, _y_ tenía todas esas desagradables limitaciones de reflexión, terminamos implementando nuestro propio serializador que usa una reflexión mínima y no se basa en BF o NDCS.

En un mundo posterior a Silverlight, el problema persiste, porque BF / NDCS no están disponibles de manera confiable en UWP, WinRT, .NET Core, etc.

Así que creo que se puede argumentar que un serializador de fidelidad completa _ debería_ existir, pero solo es realmente útil (al menos en mi opinión) si existe en todas las diversas encarnaciones de .NET.

@rockfordlhotka @opinionmachine @eiriktsarpalis Me alegra escuchar que más personas sienten lo mismo, aunque creo que sería más productivo si se dijera con un poco más de cortesía @opinionmachine , pero cada uno con lo suyo. Como este problema está cerrado, me imagino que el equipo de corefx ya no lo está monitoreando. Le aconsejo que corrija sus inquietudes en dotnet / coreclr # 2715 como lo menciona @forki

Tendría que estar de acuerdo en que eliminar la serialización (así como los dominios de aplicación) fue una idea terrible. Realmente no creo que esa decisión haya estado bien pensada.

Sin embargo, lo que realmente me motiva es que MS no lanzó el código necesario para admitir dominios de aplicaciones, etc. y dejó que la comunidad hiciera lo que quisieran con él.

Dado que se supone que coreclr es la versión de "servidor" de .net, muchas funciones del servidor se dejaron en el suelo.

Caso en cuestión: se decidió dejar StackTrace / StackFrame fuera de corefx porque fue "mal utilizado" por algunos desarrolladores, y porque rara vez se utilizó (según MS). Creo que volvieron a sus sentidos en eso (después de un montón de reacciones violentas) pero quiero decir, ¿en serio? ¿Quién piensa en estas cosas?

Por lo que vale, estoy realmente feliz con .net core y creo que es un gran paso adelante para .net, las mejoras de rendimiento son brillantes, todavía tiene casi todas las características que me importan y es multiplataforma. Este es realmente el único problema que tengo con él. Es muy valioso eliminar funciones cuando sea apropiado, solo mire el éxito que ha tenido Go con su enfoque minimalista. No es que esté diciendo que .net debería ser tan minimalista como está, eso sería ridículo, personalmente no estoy de acuerdo con un diseño minimalista, PERO lo que estoy tratando de decir es que MS no debería ser vilipendiado por eliminar ciertas características.

@SamuelCox , ¡gracias! :-)

Y para reiterar, las API faltan en .NET Core por muchas razones. Algunas de estas brechas se pueden arreglar fácilmente (y las estamos arreglando); algunos son más difíciles de arreglar. Pero queremos saber de usted sobre los problemas con los que se está enfrentando (como todo este conjunto de hilos sobre la serialización) y queremos encontrar una manera de desbloquear sus escenarios.

La serialización binaria de gráficos de objetos arbitrarios, entre versiones de un solo marco, es difícil; en diferentes marcos es aún más difícil. Y por "difícil" no me refiero a que sea difícil para nosotros hacer el trabajo. Quiero decir que tiene implicaciones de gran alcance para otros objetivos de la plataforma (objetivos que creo que todos compartimos): seguridad, rendimiento, fiabilidad.

Json.NET + TypeNameHandling.All + PreserveReferencesHandling.All + MemberSerialization.Fields lo lleva casi hasta allí. Sin embargo, no hay FormatterServices.GetUninitializedObject, por lo que debe haber un constructor disponible.

No hay FormatterServices.GetUninitializedObject

Creo que este es el problema central: los marcos de serialización externos basados ​​en la reflexión pueden ayudarlo mucho, pero esta API específica debe estar ahí para permitir que estos marcos se escriban. Mi recomendación para el equipo de CoreCLR sería volver a agregar esta API.

En algún momento, la comunidad .NET (comercial o de otro tipo) tendrá que dejar de depender de que Microsoft les lleve de la mano todo el tiempo. Si existe un requisito tan masivo para esto, y se sabe desde hace bastante tiempo que no estará disponible, ¿por qué no ha habido ninguna actividad comunitaria para proporcionar una alternativa? Json.NET es una alternativa comunitaria y la usamos todo el tiempo. Diablos, el código fuente incluso está disponible en la fuente de referencia

Parece funcionar para otras plataformas y estoy seguro de que funciona bien en .NET ... tal como yo lo veo, esta es una excelente oportunidad para crear un proyecto (que parece haber una demanda) y obtener al principio de llenar ese vacío con alternativas comunitarias

@thecodejunkie nos encantaría, pero aún necesitaríamos el tiempo de ejecución para exponer las API adecuadas para que esto suceda.

FYI: esto funciona en .NET Core: Type appDomainType = Type.GetType("System.AppDomain"); . Y sí, te permite hacer muchas cosas ...

Solo para decir que hemos mejorado la capacidad de respuesta de nuestro servidor front-end en un 30%, reducido de 12 núcleos a carga máxima a 2 núcleos a carga máxima, disminuimos el tamaño de caché de Redis de 1,7 Gb a 350 Mb en general, redujimos nuestro alojamiento de Azure en un 20% (bit más realmente)

¡Lo has adivinado BinaryFormatter!

Estaban usando netdatacontractserializer

Vine aquí buscando respuestas a que .Net 4.6.1 es mucho más lento con BinaryFormatter.

Tengo entendido que estas API volverán (serialización). Si bien no es ideal y tiene algunos problemas por ser frágil, al menos debería permitir que el código existente continúe ejecutándose.

También es valioso diseñar otro serializador de objetos simple para el marco principal, uno que también sea liviano pero que sea más resistente a problemas entre máquinas y potencialmente entre versiones.

También hay problemas de seguridad además de la fragilidad.

@blowdart WRT security, ¿te refieres a cosas como esta https://blog.scrt.ch/2016/05/12/net-serialiception/?

Sí, ese es el tipo de cosas. Cualquier formato de serialización que incluya el tipo dentro de él es peligroso, como lo está descubriendo Java este año. Me sentí increíblemente feliz cuando eliminamos la serialización binaria porque eliminamos toda una clase de vulnerabilidades.

@migueldeicaza @blowdart @SamuelCox
Los serializadores son necesarios no solo para enviar cosas, sino incluso en proceso.
Los serializadores binarios, cuando se hacen correctamente, superan por completo a todo el montón de objetos nativos cuando se trata de almacenar decenas de millones de objetos en proceso.
Mira esto:
https://www.infoq.com/articles/Big-Memory-Part-2

Las API de serialización son absolutamente necesarias para una programación de clúster sana.
Es extremadamente inconveniente teletransportar instancias de objetos CLR -> texto -> CLR, es una gran sobrecarga.
Tal vez no sea un error eliminar BinaryFormatter, ya que es MUY lento y los datagramas son enormes, pero
ese era el único serializador en el mercado además de NFX.Slim que soportaba la semántica de serialización CLR completa.
Vea las tablas detalladas de velocidad y tamaño:
http://aumcode.github.io/serbench/

ISerializable con la familia [OnSer / Deser] TIENE mucho sentido para la teletransportación en la plataforma.
No es obligatorio, como en el antiguo NET. ¿Por qué no conservarlo?
Al menos admitirlo en colecciones complejas (es decir, Diccionario), no es difícil en absoluto.

Hacer que todos usen JSON es una idea absolutamente mala, ya que es más lento que el serializador binario (no BinaryFormatter).
¿Parece que todo el mundo está creando aplicaciones similares a Twitter sin lógica empresarial?

@itadapter tiene un punto para elegir, que es que JSON.Net no es el único juego de serialización en la ciudad. También hay MsgPack, Protobuf y el propio Bond de Microsoft. (Editar: su segundo enlace llama a Protobuf). Json no es la única opción. Sin embargo, todavía existe el gran problema de serializar objetos .Net con semántica interesante (excepción).

@ RichiCoder1
Sí, por supuesto. Como se ve en los gráficos a continuación, es decir, JIL es el serilizador JSON más rápido, sin embargo, ninguno de los serializadores basados ​​en texto puede tocar los binarios. Protobuf es muy rápido a expensas de su incapacidad para admitir polimorfismo real y gráficos complejos.

Todo lo que digo es:

  • Los serializadores binarios son siempre más eficaces para los objetos de dominio empresarial, especialmente cuando tiene muchos datos numéricos.
  • Los serializadores, en general, son necesarios NO SOLO para mover datos entre sistemas, sino incluso dentro del proceso, como muestra el enfoque de Big Memory. No es un enfoque típico, pero tiene mucho sentido práctico (es decir, cachés y recorridos de gráficos sociales en memoria)
  • La "teletransportación" es una técnica similar a MS Remoting, que honestamente fue una chapuza. La comunicación remota en general cuando se hace correctamente (sin una complejidad horrible) es MUY MUY útil en los sistemas de clúster. Usamos este enfoque todo el tiempo y la programación es MUCHO más fácil con objetos nativos, cuando puede tomar objetos DOMAIN y simplemente enviarlos a otro método tal como están, ya sea en esta o en una máquina adyacente en el rack.

Puntos de referencia de una "persona típica", que muestran serializadores populares:
http://aumcode.github.io/serbench/Specimens_Typical_Person/web/overview-charts.htm

En caso de que alguien en este hilo no lo sepa, el serializador binario que incluye ISerializable, etc. se ha puesto a disposición en corefx
https://github.com/dotnet/corefx/tree/master/src/System.Runtime.Serialization.Formatters

@zhenlan ¿ Parte del trabajo .NetStandard2.0, supongo?

@ RichiCoder1 Sí, correcto.

@zhenlan es genial!

@zhenlan Parece que no puedo encontrar el atributo serializable disponible en la vista previa de Standard. ¿Me lo estoy perdiendo?

@justinhelgerson debería estar allí.

¿Instaló 2.0 Preview1 SDK como se indica en la publicación del blog del

Después de crear un proyecto .NET Core, ¿puede asegurarse de que el archivo .csproj tenga <TargetFramework>netstandard2.0</TargetFramework> si creó una biblioteca de clases o <TargetFramework>netcoreapp2.0</TargetFramework> si creó una aplicación de consola?

Por cierto, dado que muchas personas en este hilo tienen interés en el serializador binario, es posible que le interese la discusión en dotnet / corefx # 19119, que trata sobre la reducción [Serializable] para .NET Core 2.0. Háganos saber allí en caso de tener algún comentario.

@zhenlan Muchas gracias por su rápida respuesta. Había instalado la vista previa a través de NuGet, pero no actualicé manualmente mi archivo .csproj. ¡Eso hizo el truco! Leeré sobre la reducción y proporcionaré información si afectaría nuestro caso de uso.

@justinhelgerson , los cambios de

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

chunseoklee picture chunseoklee  ·  3Comentarios

jchannon picture jchannon  ·  3Comentarios

matty-hall picture matty-hall  ·  3Comentarios

omajid picture omajid  ·  3Comentarios

bencz picture bencz  ·  3Comentarios