中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用c# 如何實現進程通信

發布時間:2020-11-06 15:20:28 來源:億速云 閱讀:440 作者:Leah 欄目:開發技術

本篇文章為大家展示了使用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# 如何實現進程通信,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绍兴市| 清苑县| 扶风县| 肇庆市| 宜兰县| 定襄县| 军事| 迭部县| 定州市| 时尚| 临夏市| 斗六市| 株洲县| 桐庐县| 城步| 分宜县| 福海县| 虎林市| 理塘县| 长兴县| 嘉善县| 平舆县| 安顺市| 左云县| 卓资县| 河津市| 东宁县| 徐州市| 石家庄市| 焦作市| 福清市| 徐闻县| 湖北省| 石城县| 巴林左旗| 天气| 河间市| 牙克石市| 民县| 司法| 林州市|