非同期プログラミングとは何ですか?


Asyncプログラミングは、メインプログラムフローから独立したイベントを処理するときにパフォーマンスを向上させるプログラミングのスタイルです.たとえば、非同期であることから恩恵を受ける一般的なタスクには、次のようなものがあります.
  • ユーザインタフェースイベントの取り扱い
  • ネットワーク上での通信
  • 二次記憶装置への読み書き

  • 何が問題ですか.
    プログラマとして、同期コードでの作業に使用します.同期機能は理解しやすいです-私たちはそれらを呼び出します、彼らは若干の仕事をします、そして、彼らは値を返します.
    これが非常に悪いパフォーマンスにつながる状況があります.URLのリストによって与えられるすべてのページの内容を取得したいと思います.
    public List<string> GetAllPages(List<string> urls)
    {
        var pages = new List<string>();
        foreach (var url in urls)
        {
            pages.Add(GetPage(url));
        }
        return pages;
    }
    
    forループは、次のページを起動する前に各ページリクエストを終了するのを待つ必要があります.したがって、各関数呼び出しがブロックされているということができます.結果が返されるまで、スレッド全体がブロックされます.

    どうやってそれを修正できますか?
    非同期プログラミングは、関数呼び出しと関数の結果を分離することによってこの問題を解決するのに役立ちます.たとえば、すべてのリクエストを開始し、結果が到着するのを待つことができます.擬似コードは次のようになります.
    def GetAllPages(urls):
        pages = list()
    
        for url in urls:
            StartRequest(url)
    
        for url in urls:
            pages.Append(WaitForResponse(url))
    
    あなたが非同期にしたい操作ごとにstart関数とend関数を定義しなければならないので、これはかなり不明瞭です.ありがたいことに、Cは、これは簡単にするには良い構文があります.

    どのようにそれはCの経線で動作しますか?
    c≧では、非同期演算はTask<T> 種類"start "関数はTask 結果が得られるオブジェクトです.関数getPage ()がタスク待ちプログラミング( TAP )を使用して書き込まれた場合、次のようにプログラムを書くことができます.
    public List<string> GetAllPages(List<string> urls)
    {
        var tasks = new List<Task<string>>();
        foreach (var url in urls)
        {
            // starts the asynchronous operation
            var task = GetPage(url);
            tasks.Add(task);
        }
    
        var pages = new List<string>();
        foreach (var task in tasks)
        {
            // blocks the thread to wait for the result
            pages.Add(task.Result);
        }
    
        return pages;
    }
    
    一方、それは理想的ではない.個人は電話するがGetPage 関数をブロックしていません.GetAllPages すべてのリクエストが終了するまでブロックされます.
    これを行うには、非同期式で関数を記述できます.通常、次の3つの手順があります.
  • 追加するasync キーワード
  • 戻り値の型をTask<T>
  • 同期待ち行列を置き換えるTask.Wait() , Task.Result ) とawait キーワード
  • 前の関数は次のようになります.
    public async Task<List<string>> GetAllPages(List<string> urls)
    {
        var tasks = new List<Task<string>>();
        foreach (var url in urls)
        {
            // starts the asynchronous operation
            var task = GetPage(url);
            tasks.Add(task);
        }
    
        var pages = new List<string>();
        foreach (var task in tasks)
        {
            // doesn't block the thread
            pages.Add(await task);
        }
    
        return pages;
    }
    
    await.Resultあなたが電話するとき.Result , システムスレッドは待機してもブロックされません.
    一方、使用await 他のタスクを実行できるようにスレッドを解放します.例えば、サーバーが100クライアント(ナイーブアプローチで100システムスレッドとは対照的に)を処理するために4つのシステムスレッドだけを使用できることを意味します.
    したがって、await の代わりに使用する必要があります.Result 可能なときはいつでも.

    Note: A function must be marked async for the await keyword to be used.



    キャッチボールは何ですか.
    非同期プログラミングは、特定の状況で非常に有用です.親指のルールとして、プログラムがIOにバインドされているときにのみパフォーマンスが向上します.非同期関数を使用してCPUバインド計算を行うべきではありません.
  • ほとんど役に立たない機能性を提供します
  • コードを読みやすくする
  • パフォーマンス低下
  • この規則の1つの例外はTask.Run() 関数は、CPUのバインドされた作業をバックグラウンドスレッドで実行できるようにします.

    脚注
    あなたがこれを読んで楽しんでいるなら、私のようなものを落とすか、以下を考えてください:



  • Github
  • 私はちょうど始まっているので、サポートは大いに有り難いです!
    免責事項-私は(ほとんど)自己プログラミングプログラマであり、私は私はより良い開発になるために私の旅に学んだことを共有する私のブログを使用します.このため、私は事前に何か不正確な私が作ったかもしれない謝罪-批評と訂正が大歓迎です!