下面對匿名管道執行類似的操作。通過匿名管道,創建兩個彼此通信的任務。為了給管道的創建發出信號,使用 ManualResetEventSlim 對象,與內存映射文件一樣。在 Program 類的 Run 方法中,創建兩個任務,調用 Reader 和 Writer 方法:
private?string?_pipeHandle;?
private ManualResetEventSlim _pipeHandleSet; static void Main()
{var?p = new?Program();?p.Run();?Console.ReadLine();
}public void Run()
{ _pipeHandleSet = new ManualResetEventSlim(initialState: false); Task.Run(() => Reader()); Task.Run(() => Writer());Console.ReadLine();
}
創建一個 AnonymousPipeServerStream,定義 PipeDirection.In,把服務器端充當讀取器。通信的另一端需要知道的客戶端句柄。這個句柄在GetClientHandleAsString 方法中轉換為一個字符串,賦予 _pipeHandle 變量。這個變量以后由充當寫入器的客戶端使用。在最初的處理后,管道服務器可以作為一個流,因為它本來就是一個流:
private void Reader()
{try{var pipeReader = newAnonymousPipeServerStream(PipeDirection.In,HandleInheritability.None);using?(var?reader =?new?StreamReader(pipeReader)){_pipeHandle = pipeReader.GetClientHandleAsString(); Console.WriteLine($"pipe handle: {_pipeHandle}"); _pipeHandleSet.Set(); bool end = false; while (!end){string line = reader.ReadLine(); Console.WriteLine(line);if (line == "end") end = true;}Console.WriteLine("finished?reading");}}catch (Exception ex){Console.WriteLine(ex.Message);}
}
客戶端代碼等到變量 _pipeHandleSet 發出信號,就打開由 _pipeHandle 變量引用的管道句柄。后來的處理用 StreamWriter 繼續:
private void Writer()
{Console.WriteLine("anonymous pipe writer");_pipeHandleSet.Wait();var?pipeWriter?=?new?AnonymousPipeClientStream(?PipeDirection.Out,?_pipeHandle);using (var writer = new StreamWriter(pipeWriter)){writer.AutoFlush = true;Console.WriteLine("starting writer");for (int i = 0; i < 5; i++){writer.WriteLine($"Message {i}");Task.Delay(500).Wait();}writer.WriteLine("end");}
}
運行應用程序時,兩個任務就相互通信,在任務之間發送數據。
?微信公眾號?
DotNet講堂