C# NamePipe使用小結

來源:互聯網
上載者:User

標籤:

最近在一次項目中使用到了C#中具名管道,所以在此寫下一篇小結備忘。

為什麼要使用具名管道呢?為了實現兩個程式之間的資料交換。假設下面一個情境。在同一台PC上,程式A與程式B需要進行資料通訊,此時我們就可以使用具名管道技術來實現。具名管道的兩個對象。NamedPipeClientStream 和 NamedPipeServerStream 對象。請求通訊的一方為Client端,發送資料的一方為Server端。

使用NamedPipe來通訊,如果Server端崩潰了,不會影響到用戶端。

下面我們通過一個例子來說明:

Server端:

UI:

    <Grid>        <Grid.RowDefinitions>            <RowDefinition Height="*"/>            <RowDefinition Height="Auto"/>            <RowDefinition Height="Auto"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>        <Grid.ColumnDefinitions>            <ColumnDefinition Width="Auto"/>            <ColumnDefinition Width="*"/>        </Grid.ColumnDefinitions>                <TextBlock Text="Received Message:" Grid.Row="1" Margin="10"/>        <TextBlock x:Name="tblRecMsg" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1"/>                <Button Content="Send" Grid.Row="2" Margin="10" Click="OnSend"/>        <TextBox x:Name="txtSendMsg" VerticalAlignment="Center" Grid.Row="2" Grid.Column="1" Margin="10"/>    </Grid>

Code:

private NamedPipeServerStream _pipe;        private const string PipeName = "PipeSample";        private const int PipeInBufferSize = 4096;        private const int PipeOutBufferSize = 65535;        private Encoding encoding = Encoding.UTF8;        public MainWindow()        {            InitializeComponent();            _pipe = new NamedPipeServerStream            (                PipeName,                PipeDirection.InOut,                1,                PipeTransmissionMode.Message,                PipeOptions.Asynchronous | PipeOptions.WriteThrough,                PipeInBufferSize,                PipeOutBufferSize             );            _pipe.BeginWaitForConnection(WaitForConnectionCallback, _pipe);        }        private void WaitForConnectionCallback(IAsyncResult ar)        {            var pipeServer = (NamedPipeServerStream)ar.AsyncState;            pipeServer.EndWaitForConnection(ar);            var data = new byte[PipeInBufferSize];            var count = pipeServer.Read(data, 0, PipeInBufferSize);            if (count > 0)            {                // 通訊雙方可以約定好傳輸內容的形式,例子中我們傳輸簡單文本資訊。                string message = encoding.GetString(data, 0, count);                Dispatcher.BeginInvoke(new Action(() =>                 {                    tblRecMsg.Text = message;                }));            }        }        private void OnSend(object sender, RoutedEventArgs e)        {            if (_pipe.IsConnected)            {                try                 {                    string message = txtSendMsg.Text;                    byte[] data = encoding.GetBytes(message);                    _pipe.Write(data, 0, data.Length);                    _pipe.Flush();                    _pipe.WaitForPipeDrain();                }                catch { }            }            Close();        }

Client端:

UI:

    <Grid>        <Grid.RowDefinitions>            <RowDefinition Height="*"/>            <RowDefinition Height="Auto"/>            <RowDefinition Height="Auto"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>        <Grid.ColumnDefinitions>            <ColumnDefinition Width="Auto"/>            <ColumnDefinition Width="*"/>        </Grid.ColumnDefinitions>        <Button Content="Connect" Margin="10" Click="OnConnect"/>                <TextBlock Text="Received Message:" Grid.Row="1" Margin="10"/>        <TextBlock x:Name="tblRecMsg" Grid.Row="1" Grid.Column="1"/>    </Grid>

Code:

private const string PipeServerName = "PipeServer.exe";        private const string PipeName = "PipeSample";        private Encoding encoding = Encoding.UTF8;        private NamedPipeClientStream _pipe;        private bool _starting = false;        public MainWindow()        {            InitializeComponent();        }        private void OnConnect(object sender, RoutedEventArgs e)        {            if (_starting)            {                return;            }            var path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, PipeServerName);            var startInfo = new ProcessStartInfo(path)            {                UseShellExecute = false,                CreateNoWindow = true            };            try            {                var process = Process.Start(startInfo);                _pipe = new NamedPipeClientStream                (                    ".",                     PipeName,                     PipeDirection.InOut,                     PipeOptions.Asynchronous | PipeOptions.WriteThrough                );                _pipe.Connect();                _pipe.ReadMode = PipeTransmissionMode.Message;                string message = "Connected!";                byte[] data = encoding.GetBytes(message);                _pipe.BeginWrite(data, 0, data.Length, PipeWriteCallback, _pipe);                _starting = true;            }            catch (Exception ex)            {                Debug.Write(ex.StackTrace);            }        }        private void PipeWriteCallback(IAsyncResult ar)        {            var pipe = (NamedPipeClientStream)ar.AsyncState;            pipe.EndWrite(ar);            pipe.Flush();            pipe.WaitForPipeDrain();            var data = new byte[65535];            var count = pipe.Read(data, 0, data.Length);            if (count > 0)            {                string message = encoding.GetString(data, 0, count);                Dispatcher.BeginInvoke(new Action(() => {                    tblRecMsg.Text = message;                }));            }        }

需要注意的地方:因為我們在同一台PC上面進行通訊,我們只需要將 NamedPipeClientStream 構造參數中pipeServer設為"."即可。另外因為這隻是一個樣本,所以PipeServer中只傳遞簡單String類型。當然也可以傳遞其他類型的內容。

運行效果:

感謝您的閱讀!

C# NamePipe使用小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.