您好,登錄后才能下訂單哦!
本篇文章為大家展示了使用c# 如何實現進程通信,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
進程之間的通信是為了解決不同進程之間的數據傳輸問題,這樣可以讓不同程序交互數據。實現進程通信的方式:1、剪切板;2、COM;3、內存映射文件;4、WCF
1、剪切板Clipboard在進程間傳送對象
剪切板是一個供應用程序使用的公有區域。在.NET中定一個了一個DataFormats類,此類包含一些靜態字段,定義了剪切板中可以存放的數據類型。使用Clipboard類可以向剪切板中放入數據。
如將文字放入剪切板,使用方法SetDataObject即可:Clipboard.SetDataObject("剪切板文字2"); 在讀取的時候,先判斷剪切板中是否有文字,然后再讀取:
IDataObject data = Clipboard.GetDataObject(); if (data.GetDataPresent(DataFormats.Text)) { label1.Text = data.GetData(DataFormats.Text).ToString(); }
將自定義的數據放置到剪切板,自定義一個圖片類,并標記為可序列化(此處使用的命名空間是:TestClipboard)。將自定義數據類型對象放置到剪切板的關鍵是DataObject類,它實現了IDataObject接口。它就像一個容器,存放將被放置在剪切板上的數據。
[Serializable] public class MyPic { /// <summary> /// 圖片 /// </summary> public Image Img; /// <summary> /// 圖片信息 /// </summary> public string ImgInfo; } public void SetMyPicToClipboard() { MyPic obj = new MyPic(); obj.Img = Properties.Resources.Image; obj.ImgInfo = "測試將自定義類型保存至剪切板"; //創建數據對象,并將數據裝入 IDataObject dataObj = new DataObject(obj); //其他類型也可以放置在同一數據對象中 /* dataObj.SetData(DataFormats.UnicodeText, "測試文字"); dataObj.SetData(DataFormats.Bitmap, Properties.Resources.Image); */ //復制到剪切板,第二個參數表示程序退出時不清空 Clipboard.SetDataObject(dataObj, true); }
但是,使用Clipboard.SetDataObject方法將一個DataObject對象放到剪切板后,外界訪問時,需要指定對象的完整類型名稱。如果某種數據類型只能在指定的進程中訪問,則可以使用該方式,指定命名空間。
//首先判斷剪切板上是否有我的數據:需要完全限定命名空間類型 if (Clipboard.ContainsData("WindowsFormsApplication1.MyPic")) { IDataObject dataObj = Clipboard.GetDataObject();//讀取數據 MyPic myPic = dataObj.GetData("WindowsFormsApplication1.MyPic") as MyPic;//轉換數據 pictureBox1.Image = myPic.Img; textBox1.Text = myPic.ImgInfo; }
2、使用FileSystemWatcher實現進程同步
該組件可以監控特定的文件夾或文件,比如在此文件夾中某文件被刪除或內容被改變時引發對應的事件。通過該組件讓多個進程同時監控一個文件,以此可以充當“臨時”進程間通信渠道。
實現進程同步的關鍵點是:正確設置文件的共享和讀寫權限。
/// <summary> /// 實現寫入數據 /// </summary> /// <param name="fileName"></param> public void SetText(string fileName) { using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) { using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8)) { writer.Write("內容"); } } } /// <summary> /// 實現讀取數據 /// </summary> /// <param name="fileName"></param> public void ReadText(string fileName) { using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader reader = new StreamReader(fs, Encoding.UTF8)) { string txt = reader.ReadToEnd(); } } }
然后,使用FileSystemWatcher組件的Changed事件監控文件是否發生改變。在網絡應用程序中,可以使用此組件監控特定的專用于上傳文件的文件夾,當發現用戶上傳文件之后,系統可以自動啟動一系列的處理流程。
3、使用內存映射文件(Memory Mapped File)實現進程通信
含義:在內存中開辟一塊存放數據的專用區域,這區域與硬盤上特定的文件相對應。進程將這塊內存區域映射到自己的地址空間中,完成像訪問普通內存一樣訪問它。windows中的系統分頁文件和休眠文件就是如此實現的。需要引用命名空間System.IO.MemoryMappedFiles。
MemoryMappedFile對象表示一個內存映射文件,通過它的CreateFromFile方法根據磁盤現有文件創建內存映射文件(注意,使用完后要立即釋放資源,實際上它對應的是操作系統的核心對象)。其中,內存映射的容量在未指定時,默認與文件大小相等。在指定大小時,它的值不能小于文件的現有大小。若指定的大小大于磁盤文件大小,磁盤文件會自動增長到內存映射文件聲明的容量大小。
創建MemoryMappedFile對象后,不能直接對其進行讀寫,必須使用MemoryMappedViewAccessor對象(內存映射視圖訪問對象)操作 。可以用MemoryMappedFile對象的方法創建一個訪問對象。其中,可以指定需要訪問文件的范圍,從第幾個字節到第幾個字節。在寫入參數時,也需要指明想哪個位置寫入什么。同時也可以使用MemoryMappedViewAccessor的Read方法讀取數據。
MemoryMappedFile memoryFile = MemoryMappedFile.CreateFromFile("Text.Config", FileMode.OpenOrCreate, "Config", 1400);//kb; MemoryMappedViewAccessor accessor = memoryFile.CreateViewAccessor(0, 1024); accessor.Write(0, '2');
在同一個進程中,可以針對同一個內存映射文件創建多個“內存映射視圖訪問對象”,從而允許同時修改同一個文件的不同部分,在關閉這些對象時,由操作系統保證將所有修改都寫回原始文件。
MemoryMappedViewAccessor 的Write和Read有泛型方法,單類型只能是結構體類型(應用類型在程序運行時,計算機無法知道應該向內存映射文件寫入多少字節數據,引用類型的對象位于托管堆中,其大小需要經過計算,但非常耗時(而且對象可能引用了其他對象),音效內存映射文件的效率)。
可以使用序列化方式,將引用對象數據進行序列化后,寫入內存映射文件中。
MemoryMappedFile memoryFile = MemoryMappedFile.CreateFromFile("Text.Config", FileMode.OpenOrCreate, "Config", 1400);//kb; MemoryMappedViewStream stream = memoryFile.CreateViewStream(); MyPic obj = new MyPic(); stream.Seek(0, SeekOrigin.Begin); new BinaryFormatter().Serialize(stream, obj);
4、使用WCF通過管道實現進程通信
“管道(Pipe)”是Windows所提供的一種進程間通信機制,用于在兩個進程間相互傳送數據。Windows提供了兩種類型管道:匿名管道(Anonymous Pipe)、命名管道(Named Pipe)
在命名空間System.IO.Pipes中,提供了一些用于實現基于管道的進程間通信,如AnonymousPipeClientStream和AnonymousPipeServerStream可用于實現匿名管道,而NamedPipeClientStream和NamedPipeServerStream可以實現命名管道。但相對于WCF,其比較繁瑣,WCF的管道進程通信更加簡便和靈活。
WCF應用程序使用命名管道實現進程通信:WCF提供了一個NetNamedPipeBinding綁定,它可以在地層使用命名管道實現進程通信。
上述內容就是使用c# 如何實現進程通信,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。