AssemblyVersion
Where other assemblies that reference your assembly will look. If this number changes, other assemblies have to update their references to your assembly! Only update this version, if it breaks backward compatibility. The AssemblyVersion
is required.
I use the format: major.minor. This would result in:
[assembly: AssemblyVersion("1.0")]
If you're following SemVer strictly then this means you only update when the major changes, so 1.0, 2.0, 3.0, etc.
AssemblyFileVersion
Used for deployment. You can increase this number for every deployment. It is used by setup programs. Use it to mark assemblies that have the same AssemblyVersion
, but are generated from different builds.
In Windows, it can be viewed in the file properties.
The AssemblyFileVersion is optional. If not given, the AssemblyVersion is used.
I use the format: major.minor.patch.build, where I follow SemVer for the first three parts and use the buildnumber of the buildserver for the last part (0 for local build).
This would result in:
[assembly: AssemblyFileVersion("1.3.2.254")]
Be aware that System.Version names these parts as major.minor.build.revision
!
AssemblyInformationalVersion
The Product version of the assembly. This is the version you would use when talking to customers or for display on your website. This version can be a string, like '1.0 Release Candidate'.
The AssemblyInformationalVersion
is optional. If not given, the AssemblyFileVersion is used.
I use the format: major.minor[.patch] [revision as string]. This would result in:
[assembly: AssemblyInformationalVersion("1.0 RC1")]
Seems like string.Replace
should have an overload that takes a StringComparison
argument. Since it doesn't, you could try something like this:
public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
{
StringBuilder sb = new StringBuilder();
int previousIndex = 0;
int index = str.IndexOf(oldValue, comparison);
while (index != -1)
{
sb.Append(str.Substring(previousIndex, index - previousIndex));
sb.Append(newValue);
index += oldValue.Length;
previousIndex = index;
index = str.IndexOf(oldValue, index, comparison);
}
sb.Append(str.Substring(previousIndex));
return sb.ToString();
}
Best Solution
The solution is to use two independent
BufferedStream
s, one for receiving and one for sending. And don't forget to flush the sendingBufferedStream
appropriately.Since even in 2018 it seems hard to get a satisfying answer to this question, for the sake of humanity, here are my two cents:
The
NetworkStream
is buffered on the OS side. However, that does not mean there are no reasons to buffer on the .net side. TCP behaves well on Write-Read (repeat), but stalls on Write-Write-Read due to delayed ack, etc, etc.If you, like me, have a bunch of sub-par protocol code to take into the twentyfirst century, you want to buffer.
Alternatively, if you stick to the above, you could also buffer only reads/rcvs or only writes/sends, and use the
NetworkStream
directly for the other side, depending on how broken what code is. You just have to be consistent!What
BufferedStream
docs fail to make abundantly clear is that you should only switch reading and writing if your stream is seekable. This is because it buffers reads and writes in the same buffer.BufferedStream
simply does not work well forNetworkStream
.As Marc pointed out, the cause of this lameness is the conflation of two streams into one NetworkStream which is not one of .net's greatest design decisions.