Q: How can I run NamedPipeServerStream asynchronous? How can I run NamedPipeServerStream asynchronous?
I'm not using the pipe in another computer through a server. I'm using it only on my computer. This is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO.Pipes;
using System.Runtime.InteropServices;

namespace ScreenVideoRecorder
{
    class Ffmpeg
    {
        NamedPipeServerStream p;
        String pipename = "mytestpipe";
        byte[] b;
        //int i, j;
        System.Diagnostics.Process process;

        public Ffmpeg()
        {

        }

        public void Start(string FileName, int BitmapRate )
        {
            p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte);
            b = new byte[1920 * 1080 * 3]; // Some buffer for the R, G and B of pixels of an image of size 720p.
            process = new System.Diagnostics.Process();
            process.StartInfo.FileName = @"D:\pipetest\pipetest\ffmpegx86\ffmpeg.exe";
            process.EnableRaisingEvents = false;
            process.StartInfo.WorkingDirectory = @"D:\pipetest\pipetest\ffmpegx86";
            process.StartInfo.Arguments = @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + FileName;
            process.Start();

            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            p.WaitForConnection();
        }

Everything is working. The problem is when the process is started and I see the command prompt window and see all the work in the window. I can't get to the form. I can drag/move the command prompt window around the screen, but I can't get to the form window to click a button for example or stop the operation. I need to wait for it to finish first to do the work in the command prompt window or the window of the process.
Using the following line of code, I saw a property of the variable p to check if it's asynchronous or not but how do I set it to be asynchronous at all?
p.IsAsync

I tried to find examples, but they are all according to servers between two computers with security stuff I think.
Later, I changed this line:
p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte,PipeOptions.Asynchronous);

Added in the end: PipeOptions.Asynchronous
Now when I'm running my application, I'm getting exception on the line:
p.Write(rgbValues, 0, length);

Exception: 

InvalidOpertionException: Pipe hasn't been connected yet.

This is my full code with all changes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO.Pipes;
using System.Runtime.InteropServices;

namespace ScreenVideoRecorder
{
    class Ffmpeg
    {
        NamedPipeServerStream p;
        String pipename = "mytestpipe";
        byte[] b;
        //int i, j;
        System.Diagnostics.Process process;
        IAsyncResult ar;

        public Ffmpeg()
        {

        }

        public void Start(string FileName, int BitmapRate )
        {
            p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
            b = new byte[1920 * 1080 * 3]; // Some buffer for the R G and B of pixels of an image of size 720p.
            process = new System.Diagnostics.Process();
            process.StartInfo.FileName = @"D:\pipetest\pipetest\ffmpegx86\ffmpeg.exe";
            process.EnableRaisingEvents = false;
            process.StartInfo.WorkingDirectory = @"D:\pipetest\pipetest\ffmpegx86";
            process.StartInfo.Arguments = @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + FileName;
            process.Start();

            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            ar = p.BeginWaitForConnection(EndWait,null);
        }

        void EndWait(IAsyncResult iar)
        {
            var state = ar.AsyncState; //fetch result, mandatory!
        }

        public void PushFrame(Bitmap bmp)
        {
            int length;
            // Lock the bitmap's bits.
            //bmp = new Bitmap(1920, 1080);
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            //Rectangle rect = new Rectangle(0, 0, 1280, 720);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
                bmp.PixelFormat);

            int absStride = Math.Abs(bmpData.Stride);
            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            //length = 3 * bmp.Width * bmp.Height;
            length = absStride * bmpData.Height;
            byte[] rgbValues = new byte[length];

            //Marshal.Copy(ptr, rgbValues, 0, length);
            int j = bmp.Height - 1;
            for (int i = 0; i < bmp.Height; i++)
            {
                IntPtr pointer = new IntPtr(bmpData.Scan0.ToInt32() + (bmpData.Stride * j));
                System.Runtime.InteropServices.Marshal.Copy(pointer, rgbValues, absStride * (bmp.Height - i - 1), absStride);
                j--;
            }

            p.Write(rgbValues, 0, length);
            bmp.UnlockBits(bmpData);

The exception message:
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Pipe hasn't been connected yet.
  Source=System.Core
  StackTrace:
       at System.IO.Pipes.PipeStream.CheckWriteOperations()
       at System.IO.Pipes.PipeStream.Write(Byte[] buffer, Int32 offset, Int32 count)
       at ScreenVideoRecorder.Ffmpeg.PushFrame(Bitmap bmp) in d:\C-Sharp\ScreenVideoRecorder\ScreenVideoRecorderWorkingVersion\Ffmpeg.cs:line 77
       at ScreenVideoRecorder.Form1.StartRecording_Click(Object sender, EventArgs e) in d:\C-Sharp\ScreenVideoRecorder\ScreenVideoRecorderWorkingVersion\Form1.cs:line 53
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at ScreenVideoRecorder.Program.Main() in d:\C-Sharp\ScreenVideoRecorder\ScreenVideoRecorderWorkingVersion\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:


A: When you use NamedPipeServerStream.WaitForConnection your current thread will block until the operation has finished.
You can use BeginWaitForConnection to create a thread that will work in background.
Using the returned IAsyncResult, you can fetch the result of the asynchronous operation. 
From MSDN:
The IAsyncResult interface is implemented by classes containing methods that can operate asynchronously. It is the return type of methods that initiate an asynchronous operation, such as FileStream.BeginRead, and it is passed to methods that conclude an asynchronous operation, such as FileStream.EndRead. IAsyncResult objects are also passed to methods invoked by AsyncCallback delegates when an asynchronous operation completes.
An object that supports the IAsyncResult interface stores state information for an asynchronous operation and provides a synchronization object to allow threads to be signaled when the operation completes.

class Ffmpeg
{
    NamedPipeServerStream p;
    String pipename = "mytestpipe";
    byte[] b;
    //int i, j;
    System.Diagnostics.Process process;
    IAsyncResult ar;

    public Ffmpeg()
    {

    }

    public void Start(string FileName, int BitmapRate )
    {
        p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte);
        b = new byte[1920 * 1080 * 3]; // some buffer for the r g and b of pixels of an image of size 720p 
        process = new System.Diagnostics.Process();
        process.StartInfo.FileName = @"D:\pipetest\pipetest\ffmpegx86\ffmpeg.exe";
        process.EnableRaisingEvents = false;
        process.StartInfo.WorkingDirectory = @"D:\pipetest\pipetest\ffmpegx86";
        process.StartInfo.Arguments = @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + FileName;
        process.Start();

        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = false;
        ar = p.BeginWaitForConnection(EndWait, null);
    }

//callback when client connects
void EndWait(IAsyncResult iar){
    var state = iar.AsyncState; // fetch state -> cast to desired type
    //do something when client connected
}

