最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#編程總結(jié)(六)詳解異步編程

 更新時(shí)間:2016年12月01日 09:57:15   作者:停留的風(fēng)  
本篇文章主要介紹了C#異步編程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧。

1、什么是異步?

異步操作通常用于執(zhí)行完成時(shí)間可能較長的任務(wù),如打開大文件、連接遠(yuǎn)程計(jì)算機(jī)或查詢數(shù)據(jù)庫。異步操作在主應(yīng)用程序線程以外的線程中執(zhí)行。應(yīng)用程序調(diào)用方法異步執(zhí)行某個(gè)操作時(shí),應(yīng)用程序可在異步方法執(zhí)行其任務(wù)時(shí)繼續(xù)執(zhí)行。

2、同步與異步的區(qū)別

同步(Synchronous):在執(zhí)行某個(gè)操作時(shí),應(yīng)用程序必須等待該操作執(zhí)行完成后才能繼續(xù)執(zhí)行。

異步(Asynchronous):在執(zhí)行某個(gè)操作時(shí),應(yīng)用程序可在異步操作執(zhí)行時(shí)繼續(xù)執(zhí)行。實(shí)質(zhì):異步操作,啟動(dòng)了新的線程,主線程與方法線程并行執(zhí)行。

3、異步和多線程的區(qū)別   

我們已經(jīng)知道,異步的實(shí)質(zhì)是開啟了新的線程。它與多線程的區(qū)別是什么呢?

簡單的說就是:異步線程是由線程池負(fù)責(zé)管理,而多線程,我們可以自己控制,當(dāng)然在多線程中我們也可以使用線程池。

就拿網(wǎng)絡(luò)扒蟲而言,如果使用異步模式去實(shí)現(xiàn),它使用線程池進(jìn)行管理。異步操作執(zhí)行時(shí),會(huì)將操作丟給線程池中的某個(gè)工作線程來完成。當(dāng)開始I/O操作的時(shí)候,異步會(huì)將工作線程還給線程池,這意味著獲取網(wǎng)頁的工作不會(huì)再占用任何CPU資源了。直到異步完成,即獲取網(wǎng)頁完畢,異步才會(huì)通過回調(diào)的方式通知線程池??梢?,異步模式借助于線程池,極大地節(jié)約了CPU的資源。

注:DMA(Direct Memory Access)直接內(nèi)存存取,顧名思義DMA功能就是讓設(shè)備可以繞過處理器,直接由內(nèi)存來讀取資料。通過直接內(nèi)存訪問的數(shù)據(jù)交換幾乎可以不損耗CPU的資源。在硬件中,硬盤、網(wǎng)卡、聲卡、顯卡等都有直接內(nèi)存訪問功能。異步編程模型就是讓我們充分利用硬件的直接內(nèi)存訪問功能來釋放CPU的壓力。

兩者的應(yīng)用場景:

計(jì)算密集型工作,采用多線程。

IO密集型工作,采用異步機(jī)制。

4、異步應(yīng)用

.NET Framework 的許多方面都支持異步編程功能,這些方面包括:

      1)文件 IO、流 IO、套接字 IO。

      2)網(wǎng)絡(luò)。

      3)遠(yuǎn)程處理信道(HTTP、TCP)和代理。

      4)使用 ASP.NET 創(chuàng)建的 XML Web services。

      5)ASP.NET Web 窗體。

      6)使用 MessageQueue 類的消息隊(duì)列。

.NET Framework 為異步操作提供兩種設(shè)計(jì)模式:

      1)使用 IAsyncResult 對(duì)象的異步操作。

      2)使用事件的異步操作。

IAsyncResult 設(shè)計(jì)模式允許多種編程模型,但更加復(fù)雜不易學(xué)習(xí),可提供大多數(shù)應(yīng)用程序都不要求的靈活性??赡艿脑挘悗煸O(shè)計(jì)者應(yīng)使用事件驅(qū)動(dòng)模型實(shí)現(xiàn)異步方法。在某些情況下,庫設(shè)計(jì)者還應(yīng)實(shí)現(xiàn)基于 IAsyncResult 的模型。

使用 IAsyncResult 設(shè)計(jì)模式的異步操作是通過名為 Begin操作名稱和End操作名稱的兩個(gè)方法來實(shí)現(xiàn)的,這兩個(gè)方法分別開始和結(jié)束異步操作操作名稱。例如,F(xiàn)ileStream 類提供 BeginRead 和 EndRead 方法來從文件異步讀取字節(jié)。這兩個(gè)方法實(shí)現(xiàn)了 Read 方法的異步版本。在調(diào)用 Begin操作名稱后,應(yīng)用程序可以繼續(xù)在調(diào)用線程上執(zhí)行指令,同時(shí)異步操作在另一個(gè)線程上執(zhí)行。每次調(diào)用 Begin操作名稱 時(shí),應(yīng)用程序還應(yīng)調(diào)用 End操作名稱來獲取操作的結(jié)果。Begin操作名稱 方法開始異步操作操作名稱并返回一個(gè)實(shí)現(xiàn) IAsyncResult 接口的對(duì)象。 .NET Framework 允許您異步調(diào)用任何方法。定義與您需要調(diào)用的方法具有相同簽名的委托;公共語言運(yùn)行庫將自動(dòng)為該委托定義具有適當(dāng)簽名的 BeginInvoke 和 EndInvoke 方法。  

IAsyncResult 對(duì)象存儲(chǔ)有關(guān)異步操作的信息。下表提供了有關(guān)異步操作的信息。

名稱        

說明

AsyncState

獲取用戶定義的對(duì)象,它限定或包含關(guān)于異步操作的信息。

AsyncWaitHandle

獲取用于等待異步操作完成的 WaitHandle。

CompletedSynchronously

獲取一個(gè)值,該值指示異步操作是否同步完成。

IsCompleted

獲取一個(gè)值,該值指示異步操作是否已完

5、應(yīng)用實(shí)例

案例1-讀取文件

通常讀取文件是一個(gè)比較耗時(shí)的工作,特別是讀取大文件的時(shí)候,常見的上傳和下載。但是我們又不想讓用戶一直等待,用戶同樣可以進(jìn)行其他操作,可以使得系統(tǒng)有良好的交互性。這里我們寫了同步調(diào)用和異步調(diào)用來進(jìn)行比較說明。

讀取文件類

using System;
using System.IO;
using System.Threading;

namespace AsynSample
{
  class FileReader
  {
    /// <summary>
    /// 緩存池
    /// </summary>
    private byte[] Buffer { get; set; }
    /// <summary>
    /// 緩存區(qū)大小
    /// </summary>
    public int BufferSize { get; set; }

    public FileReader(int bufferSize)
    {
      this.BufferSize = bufferSize;
      this.Buffer = new byte[BufferSize];
    }

    /// <summary>
    /// 同步讀取文件
    /// </summary>
    /// <param name="path">文件路徑</param>
    public void SynsReadFile(string path)
    {
      Console.WriteLine("同步讀取文件 begin");
      using (FileStream fs = new FileStream(path, FileMode.Open))
      {        
        fs.Read(Buffer, 0, BufferSize);
        string output = System.Text.Encoding.UTF8.GetString(Buffer);
        Console.WriteLine("讀取的文件信息:{0}",output);
      }
      
      Console.WriteLine("同步讀取文件 end");
    }
    /// <summary>
    /// 異步讀取文件
    /// </summary>
    /// <param name="path"></param>
    public void AsynReadFile(string path)
    {
      Console.WriteLine("異步讀取文件 begin");
      //執(zhí)行Endread時(shí)報(bào)錯(cuò),fs已經(jīng)釋放,注意在異步中不能使用釋放需要的資源
      //using (FileStream fs = new FileStream(path, FileMode.Open))
      //{
      //  Buffer = new byte[BufferSize];
      //  fs.BeginRead(Buffer, 0, BufferSize, AsyncReadCallback, fs);
      //} 
      if (File.Exists(path))
      {
        FileStream fs = new FileStream(path, FileMode.Open);
        fs.BeginRead(Buffer, 0, BufferSize, AsyncReadCallback, fs);
      }
      else
      {
        Console.WriteLine("該文件不存在");
      }

    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="ar"></param>
    void AsyncReadCallback(IAsyncResult ar)
    {
      FileStream stream = ar.AsyncState as FileStream;
      if (stream != null)
      {
        Thread.Sleep(1000);
        //讀取結(jié)束
        stream.EndRead(ar);
        stream.Close();

        string output = System.Text.Encoding.UTF8.GetString(this.Buffer);
        Console.WriteLine("讀取的文件信息:{0}", output);
      }
    }
  }
}

測試用例

using System;
using System.Threading;

namespace AsynSample
{
  class Program
  {
    static void Main(string[] args)
    {
      FileReader reader = new FileReader(1024);

      //改為自己的文件路徑
      string path = "C:\\Windows\\DAI.log";

      Console.WriteLine("開始讀取文件了...");
      //reader.SynsReadFile(path);

      reader.AsynReadFile(path);

      Console.WriteLine("我這里還有一大灘事呢.");
      DoSomething();
      Console.WriteLine("終于完事了,輸入任意鍵,歇著!");
      Console.ReadKey();      
    }
    /// <summary>
    /// 
    /// </summary>
    static void DoSomething()
    {
      Thread.Sleep(1000);
      for (int i = 0; i < 10000; i++)
      {
        if (i % 888 == 0)
        {
          Console.WriteLine("888的倍數(shù):{0}",i);
        }
      }
    }
  }
}

輸出結(jié)果:

同步輸出:


異步輸出:


結(jié)果分析:

如果是同步讀取,在讀取時(shí),當(dāng)前線程讀取文件,只能等到讀取完畢,才能執(zhí)行以下的操作

而異步讀取,是創(chuàng)建了新的線程,讀取文件,而主線程,繼續(xù)執(zhí)行。我們可以開啟任務(wù)管理器來進(jìn)行監(jiān)視。

案例二--基于委托的異步操作

系統(tǒng)自帶一些類具有異步調(diào)用方式,如何使得自定義對(duì)象也具有異步功能呢?

我們可以借助委托來輕松實(shí)現(xiàn)異步。

說到BeginInvoke,EndInvoke就不得不停下來看一下委托的本質(zhì)。為了便于理解委托,我定義一個(gè)簡單的委托:

public delegate string MyFunc(int num, DateTime dt);

我們?cè)賮砜匆幌逻@個(gè)委托在編譯后的程序集中是個(gè)什么樣的:

委托被編譯成一個(gè)新的類型,擁有BeginInvoke,EndInvoke,Invoke這三個(gè)方法。前二個(gè)方法的組合使用便可實(shí)現(xiàn)異步調(diào)用。第三個(gè)方法將以同步的方式調(diào)用。 其中BeginInvoke方法的最后二個(gè)參數(shù)用于回調(diào),其它參數(shù)則與委托的包裝方法的輸入?yún)?shù)是匹配的。 EndInvoke的返回值與委托的包裝方法的返回值匹配。

異步實(shí)現(xiàn)文件下載:

using System;
using System.Text;

namespace AsynSample
{
  /// <summary>
  /// 下載委托
  /// </summary>
  /// <param name="fileName"></param>
  public delegate string AysnDownloadDelegate(string fileName);
  /// <summary>
  /// 通過委托實(shí)現(xiàn)異步調(diào)用
  /// </summary>
  class DownloadFile
  {
    /// <summary>
    /// 同步下載
    /// </summary>
    /// <param name="fileName"></param>
    public string Downloading(string fileName)
    {
      string filestr = string.Empty;
      Console.WriteLine("下載事件開始執(zhí)行");
      System.Threading.Thread.Sleep(3000);
      Random rand = new Random();
      StringBuilder builder =new StringBuilder();
      int num;
      for(int i=0;i<100;i++)
      {
        num = rand.Next(1000);
        builder.Append(i);
      }
      filestr = builder.ToString();
      Console.WriteLine("下載事件執(zhí)行結(jié)束");

      return filestr;
    }
    /// <summary>
    /// 異步下載
    /// </summary>
    public IAsyncResult BeginDownloading(string fileName)
    {
      string fileStr = string.Empty;
      AysnDownloadDelegate downloadDelegate = new AysnDownloadDelegate(Downloading);
      return downloadDelegate.BeginInvoke(fileName, Downloaded, downloadDelegate);
    }
    /// <summary>
    /// 異步下載完成后事件
    /// </summary>
    /// <param name="result"></param>
    private void Downloaded(IAsyncResult result)
    {
      AysnDownloadDelegate aysnDelegate = result.AsyncState as AysnDownloadDelegate;
      if (aysnDelegate != null)
      {
        string fileStr = aysnDelegate.EndInvoke(result);
        if (!string.IsNullOrEmpty(fileStr))
        {
          Console.WriteLine("下載文件:{0}", fileStr);
        }
        else
        {
          Console.WriteLine("下載數(shù)據(jù)為空!");
        }
      }
      else
      {
        Console.WriteLine("下載數(shù)據(jù)為空!");
      }
    }
  }
}


通過案例,我們發(fā)現(xiàn),使用委托能夠很輕易的實(shí)現(xiàn)異步。這樣,我們就可以自定義自己的異步操作了。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#數(shù)據(jù)結(jié)構(gòu)之單鏈表(LinkList)實(shí)例詳解

    C#數(shù)據(jù)結(jié)構(gòu)之單鏈表(LinkList)實(shí)例詳解

    這篇文章主要介紹了C#數(shù)據(jù)結(jié)構(gòu)之單鏈表(LinkList)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了單鏈表的原理、定義與C#具體實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 在C#中如何使用JSON

    在C#中如何使用JSON

    JSON(JavaScript?Object?Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,具有易讀、易解析的特點(diǎn),廣泛用于API數(shù)據(jù)交互、配置文件等,本文介紹在C#中如何使用JSON,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • c#獲取gridview的值代碼分享

    c#獲取gridview的值代碼分享

    這篇文章主要介紹了C#如何在事件中獲得GridView里面TextBox的值,大家參考使用吧
    2013-12-12
  • C#編程簡單實(shí)現(xiàn)生成PDF文檔的方法示例

    C#編程簡單實(shí)現(xiàn)生成PDF文檔的方法示例

    這篇文章主要介紹了C#編程簡單實(shí)現(xiàn)生成PDF文檔的方法,結(jié)合實(shí)例形式分析了C#生成PDF文檔的具體步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-07-07
  • C#對(duì)Windows服務(wù)組的啟動(dòng)與停止操作

    C#對(duì)Windows服務(wù)組的啟動(dòng)與停止操作

    這篇文章主要為大家詳細(xì)介紹了C#對(duì)Windows服務(wù)組的啟動(dòng)與停止操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Unity shader實(shí)現(xiàn)遮罩效果

    Unity shader實(shí)現(xiàn)遮罩效果

    這篇文章主要為大家詳細(xì)介紹了Unity shader實(shí)現(xiàn)遮罩效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#實(shí)現(xiàn)讀取匿名對(duì)象屬性值的方法示例總結(jié)

    C#實(shí)現(xiàn)讀取匿名對(duì)象屬性值的方法示例總結(jié)

    這篇文章主要介紹了C#實(shí)現(xiàn)讀取匿名對(duì)象屬性值的方法,結(jié)合實(shí)例形式總結(jié)分析了C#通過反射、轉(zhuǎn)換等方法讀取匿名對(duì)象屬性值的相關(guān)操作技巧,需要的朋友可以參考下
    2020-03-03
  • C# winform分頁查詢的實(shí)現(xiàn)示例

    C# winform分頁查詢的實(shí)現(xiàn)示例

    這篇文章主要介紹了C# winform分頁查詢的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Unity2021發(fā)布WebGL與網(wǎng)頁交互問題的解決

    Unity2021發(fā)布WebGL與網(wǎng)頁交互問題的解決

    本文主要介紹了Unity2021發(fā)布WebGL與網(wǎng)頁交互問題的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Unity實(shí)現(xiàn)簡單虛擬搖桿

    Unity實(shí)現(xiàn)簡單虛擬搖桿

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)簡單虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評(píng)論

青阳县| 海南省| 北海市| 随州市| 淳安县| 定兴县| 边坝县| 大姚县| 龙南县| 台南市| 武川县| 辰溪县| 兴海县| 清流县| 峨边| 肥东县| 长顺县| 正定县| 伊川县| 克拉玛依市| 盐山县| 宜兴市| 垦利县| 商丘市| 洛宁县| 茌平县| 上犹县| 驻马店市| 昭平县| 武冈市| 偃师市| 固镇县| 东至县| 锡林郭勒盟| 巧家县| 河西区| 阿瓦提县| 石城县| 大宁县| 乌苏市| 璧山县|