I have an application that processes video with additional graphics and displays the output in a Windows Form. I had to separate the video processing into a background process/service and displaying the video/frames to a frontend UI. The images are sent via named pipes as soon as they are ready.
Everything works, but the issue is that sending the video through the named pipe is very slow. Here's the relevant code:
Background process:
if (serverPipe.isConnected()) {
ImageConverter converter = new ImageConverter();
erverPipe.WriteBytes((byte[])converter.ConvertTo(_currentImage.ToBitmap(), typeof(byte[])));
serverPipe.Flush();
}
Foreground UI app:
clientPipe.DataReceived += (sndr, args) =>
{
form.updatePictureBox(args.Data);
};
The named pipe code is from this post:
c# Full Duplex Asynchronous Named Pipes .NET
Github link: https://github.com/cliftonm/clifton/tree/master/Clifton.Core/Clifton.Core.Pipes
The FPS that I get through the named pipe is close to 1 or 2 frames per second. I'm not sure if I'm dealing with a limitation in the way named pipes work or an inefficiency in my code.
I wrote a client and a server console app using the library you mentioned and on my machine it takes about 50-60ms to send 4 MB of data between the two processes. Therefore I think that you do not deal with a named pipe limitation. I suggest that you try to measure the other parts of your code and try to narrow down what the cause for the low FPS is.
Server
using Clifton.Core.Pipes;
using System;
using System.Diagnostics;
namespace NamedPipeTest
{
class Program
{
static void Main(string[] args)
{
StartServer();
Console.ReadLine();
}
private static void StartServer()
{
ServerPipe serverPipe = new ServerPipe("Test", p => p.StartByteReaderAsync());
var sw = new Stopwatch();
serverPipe.Connected += (s, ea) => {
Console.WriteLine("Server connected");
sw.Start();
};
serverPipe.DataReceived += (s, ea) => {
Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}\t {sw.ElapsedMilliseconds}\t Data received. Length: {ea.Len}");
sw.Restart();
};
}
}
Client
using Clifton.Core.Pipes;
using System;
namespace NamedPipeTest
{
class Program
{
static void Main(string[] args)
{
StartClient(iterations: 100);
Console.ReadLine();
}
private static void StartClient(int iterations)
{
ClientPipe clientPipe = new ClientPipe(".", "Test", p => p.StartByteReaderAsync());
clientPipe.Connect();
byte[] data = CreateRandomData(sizeMb: 4);
for (int i = 0; i < iterations; i++)
{
clientPipe.WriteBytes(data);
Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}\t Wrote data {i}");
}
}
private static byte[] CreateRandomData(int sizeMb)
{
var data = new byte[1024 * 1024 * sizeMb];
new Random().NextBytes(data);
return data;
}
}
}