I am using BinaryFormatter to send different message types via TCP.
I use the following code to transmit a MessageBase derived class:
private void TransmittingThread()
{
log.Debug("TCPCommunicationLayer - TransmittingThread Startting");
while (IsRunning)
{
try
{
// This blocks until a message is available
MessageBase msg = MessageQueue.Take();
if (msg != null)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
BinaryFormatter f = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
f.Serialize(ms, msg);
long msgSize = ms.Length;
log.Debug($"Transmitting - {msg.Report(true)} - {msgSize} Bytes - {stopWatch.ElapsedMilliseconds} ms");
f.Serialize(_client.GetStream(), msg);
stopWatch.Stop();
log.Debug($"Transmitted - {msg.Report(true)} - {stopWatch.ElapsedMilliseconds} ms");
ms.Close();
}
}
catch (Exception e)
{
log.Error(e);
Disconnect();
}
}
while (MessageQueue.TryTake(out _)) { }
log.Debug("TCPCommunicationLayer - TransmittingThread Exiting");
}
MessageBase is defined as:
[Serializable]
public abstract class MessageBase
{
protected MessageBase(string name)
{
Name = name;
Guid = Guid.NewGuid();
}
public Guid Guid { get; }
public string Name { get; }
}
[Serializable]
public class ParameterMessage<T> : MessageBase
{
public ParameterMessage(string name, T data)
: base(name)
{
Data = data;
}
public T Data { get; }
}
The following class which is about 5 Mb in size takes about 500 ms to transmit:
[Serializable]
public class SharedPreview : SharedPreviewParameters
{
private byte[] _previewImageBuffer = Array.Empty<byte>();
private byte[] _labelImageBuffer = Array.Empty<byte>();
public SharedPreview(ScanInfo scanInfo, List<RegionOfInterest> regionsOfInterest, List<PredictiveFocusPoint> predictiveFocusPoints)
: base(scanInfo, regionsOfInterest, predictiveFocusPoints)
{
}
private byte[] EncodeImage(BitmapImage image)
{
// ...
}
private BitmapImage ExtractImage(byte[] buffer)
{
// ...
}
}
But the following class which is only 200 Kb takes about 20 seconds:
[Serializable]
public class ClientLogDefinition
{
public string Filename { get; set; }
public string FullPath { get; set; }
public string Content { get; set; }
}
[Serializable]
public class SharedClientLogs
{
public List<ClientLogDefinition> ClientLogs { get; } = new List<ClientLogDefinition>();
}
I realize I could convert the strings to byte arrays which might solve the issue but I would really like to know what is causing the very slow performance with large strings