44

I have a client winform application that connects to the local network server of WCF. There has a performance issue on the client side and I searched for the solution and found this post.

It says there that:

This sounds like the serialization assemblies being created at runtime. Try changing the settings of the Serialization Assembly dropdown at the bottom of the Build pane of the properties window for the project.

My question is When to change the Generate Serialization Assembly value and what value should I change it into to improve the performance of my client side application?

My code is in C#, framework 4, build in VS2010Pro.

starball
  • 20,030
  • 7
  • 43
  • 238
John Isaiah Carmona
  • 5,260
  • 10
  • 45
  • 79

1 Answers1

69

In order to serialize classes/structs, serialization assemblies need to be generated. This can happen at compiletime or runtime. Sgen.exe is used to generate serialization assemblies at compiletime; Visual Studio can optionally automate this process, as you have discovered.

  • Off: Default for Debug configurations (thanks, @Alexandru Lache). Do not generate serialization assemblies at compiletime. Serialization assemblies will be generated each time the application runs, according to MSDN:

    When the XML Serializer Generator is not used, a XmlSerializer generates serialization code and a serialization assembly for each type every time an application is run. To improve the performance of XML serialization startup, use the Sgen.exe tool to generate those assemblies the assemblies in advance. These assemblies can then be deployed with the application.

  • On: Use Sgen.exe to generate a serialization assembly at compiletime. This saves startup time, but increases deployment size.
  • Auto: Default for Release configurations. Officially, only generates assembly if XmlSerializer is used in your code, per MSDN (thanks, @L-Three). In my tests, this didn't always work, so I recommend explicitly setting it to On if you are using XmlSerializer.

So, my answer would be this: if you are concerned about startup time, and you use the Serializable attribute even once, set the option to On. If you are more concerned about deployment size, change it to Off. I never leave it on Auto anymore, because I don't trust it. Like I said, it seems to be the same as Off, but I wouldn't count on it.

Edit: I'm definitely having some trouble differentiating between Off and Auto. The difference isn't clearly defined anywhere. I'd stick with On if you use the Serializable attribute at all, and Off if you don't. I wouldn't take deployment size or startup time into account. I just seem to run into fewer serialization-related bugs if I stick to that rule.

Update:

After a review of the sources mentioned, I believe "startup" refers to the first time an XmlSerializer is used on any given type, not initial application launch. I can't be sure; it's a bit ambiguous.

Community
  • 1
  • 1
Zenexer
  • 18,788
  • 9
  • 71
  • 77
  • 1
    One remark: the `[Serializable]` attribute is related to binary serialization, not XML serialization. So, you should consider using this if you are using the `XmlSerializer` class and you are concerned about time needed to (de)serialize the first object instance. – vgru Jun 04 '13 at 09:39
  • @Groo No, `SerializableAttribute` is for all forms of serialization, not just binary serialization. See [MSDN](http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx). – Zenexer Jun 06 '13 at 22:28
  • 4
    When you say "all forms of serialization", I believe you are talking about different serialization formatters used by the [.NET runtime serialization](http://msdn.microsoft.com/en-us/magazine/cc301761.aspx). But the `XmlSerializer` class is not related to .NET runtime serialization, it is the only class which uses these generated serialization assemblies (runtime serialization and WCF data contracts do not use them), and it has nothing to do with the `[Serializable]` attribute. A class only needs to be `public` and have a public parameterless constructor for `XmlSerializer` to work. – vgru Jun 07 '13 at 15:17
  • @Groo, I am not talking about .NET runtime serialization. I am talking about serialization, period. All serializable types *should* be documented with a `SerializableAttribute` attribute. For some forms of serialization, as you pointed out, they *must* be marked. – Zenexer Jun 08 '13 at 17:20
  • 2
    I strongly disagree with this "should be" convention you mention. Where did you read that? If public members of a class can be serialized, it doesn't mean it is safe to serialize it with runtime serialization. You are only creating a potential security and stability risk, allowing unwanted serialization of its private fields. See [Drawbacks of marking a class as Serializable](http://stackoverflow.com/q/1236857/69809), [Why classes are not Serializable by default?](http://stackoverflow.com/q/4408909/69809), [Disadvantage of making class Serializable](http://stackoverflow.com/q/12754688/69809). – vgru Jun 09 '13 at 09:18
  • The point of my comment was to indicate that 1. `SerializableAttribute` is not used by `XmlSerializer`, and 2. only `XmlSerializer` uses serialization assemblies, and you answer is misguiding. So, again, this part of your answer: *"[if] you use the `Serializable` attribute even once, set the option to On"*, is wrong. `Serializable` *does not* mean you are using `XmlSerializer`, but it *should* mean you checked that your classes can be safely serialized with runtime serialization. And runtime serialization does not use generated serialization assemblies. – vgru Jun 09 '13 at 09:21
  • @Groo `SerializableAttribute` is an attribute. It doesn't _do_ anything. It is much like a permission. `IFormatter` implementations use it to determine whether an object has permission to be serialized. XML serialization is very common. It does not serialize private fields, unlike other forms of serialization, so it is not a security risk, if an application is designed properly. Generally, providing this option is a good idea in modern code. Granted, if you are sure that XML won't be used, the serialization assembly is useless, but `SerializableAttribute` should still be used. – Zenexer Jun 11 '13 at 03:34
  • You again state that *"`SerializableAttribute` should still be used"*, with no explanation at all. Why? Why would you "permit" serialization of private members for classes you are not going to serialize? Would you leave your car open with a message "permission to enter"? Sure, you didn't steal your own car, you merely gave permission for others to do it. Maybe you'll decide that cars "should" be left open. But the question is **why**? There are known issues with doing so, and I see no reason **why** you would still insist on doing it and act like it's some sort of a guideline. – vgru Jun 11 '13 at 13:40
  • @Groo I think you misunderstood. I meant that you should use `SerializableAttribute` on all classes that are going to be serialized, or rather, that should logically be serializable. It certainly shouldn't be on all types--that would be silly. – Zenexer Jun 11 '13 at 22:15
  • 17
    Please note Auto on DEBUG is Off and on RELEASE is On. – Alexandru Lache Aug 19 '13 at 08:23
  • "By default, this option is set to Auto, which specifies that serialization assemblies be generated only if you have used XmlSerializer to encode types in your code to XML." (http://msdn.microsoft.com/en-us/library/kb4wyys2.aspx) – L-Four Jul 04 '14 at 11:20
  • @Groo Looking back on this, the answer is that you should use `[Serializable]` because without it, Sgen doesn't know which types to include in the serialization assembly. – Zenexer Jul 14 '14 at 18:31
  • @Zenexer: No, that is still incorrect. `XmlSerializer` is completely unrelated to the `[Serializable]` attribute. [Sgen](http://msdn.microsoft.com/en-us/library/bk3w6240(v=vs.110).aspx) generates serialization code for **all** types included in an assembly, regardless of the attribute. If you really want, you can use the `/t` switch to specify the exact type, but the default behavior is to create code for all types. I don't really understand why you decided to edit your answer with incorrect information. MSDN clearly describes how Sgen works. – vgru Jul 15 '14 at 20:47
  • @Groo I noted that I wasn't sure; I didn't see anything definitive on MSDN about which types it operates on. Regardless, it's still a good practice to mark serializable classes as such. Some classes simply cannot be serialized (reasonably), even with `XmlSerializer`. – Zenexer Jul 16 '14 at 03:20
  • Was having a build issue and came across this which helped. But for clarification, I think from the following two links it is clear that `XmlSerializer` and `[Serializable]` are not related ([SerializableAttribute](https://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx) and [Attributes for Xml Serialization](https://msdn.microsoft.com/en-us/library/83y7df3e.aspx)). Based on this conversation, I would have to agree that `[Serializable]` should only be used if absolutely necessary like storing the objects in Session or Cache. – Ron Mar 13 '15 at 13:21
  • Do WCF data contracts use serialization assemblies? – beppe9000 Mar 04 '16 at 18:20