.NETの世界での「非同期」とは、非同期処理(主に非同期I/O)を効率よく、しかも最小のプログラミングコストで実現するため、コンパイラとライブラリの補助で実現する機能の事です。C#やVB.netにおいて、「async-await」キーワードを使って、ほぼ従来通りのフローコーデイングを実現可能で、コンパイラが自動的に複雑なステート管理に展開してくれるため、人的なエラーを起こしにくく、コード量も飛躍的に削減出来ます。
これまでの非同期処理のセオリーは、プロセスレベルやスレッドレベルで、いわゆる「ワーカープロセス・スレッド」を使ってオフロード処理する方法が主流でした。この方法の問題点は、メインの処理とワーカーとの間で行わなければならない同期処理や、ワーカー処理がI/Oのブロッキングを保持するためだけにCPUリソースを消費(プロセスやスレッドを使う)してしまう事でした。.NETの非同期処理は、非同期I/Oにほぼ直結した操作を実現可能であり、更にCPU依存性処理もまったく同じ操作に統合する事が出来ます。
C#の非同期メソッド構文をベースに、JavaScript(ECMAScript)の将来のバージョンや、他の言語へも同様のセマンティックスでの導入が実現しつつあります。
// ファイルを非同期で読み取りながら、行数を数える public async Task<int> CountTextLinesAsync(string path) { using (var stream = File.Open(path, FileMode.Open)) { var tr = new StreamReader(stream); var count = 0; while (true) { // 非同期で一行読み取る var line = await tr.ReadLineAsync(); if (line == null) { break; } count++; } return count; } } // フォルダの全てのテキストファイルの行数を非同期で並列計測する public async Task<int> CountTextFilesAsync(string path) { // フォルダ内のファイルを並列計測して、最後に集計して返す return (await Task.WhenAll( Directory.EnumerateFiles(path, "*.txt"). Select(CountTextLinesAsync))). Sum(); }
固定ページは書いた順に紹介するようにしているのですが、初心者が非同期処理でハマらないように、敢えてこの2つの記事を先頭に持ってきています。
非同期処理、なにもわからない
非同期処理を書こうとして、溶岩地帯に突っ込んでしまう事例を、日常描画風に書いてみました。下の、「できる!」より、こちらの方が分かりやすい人もいるかも知れません。
技術レベル : 100
できる!C#で非同期処理(Taskとasync-await)
非同期処理を始めてみようとしているのなら、まずこの記事を参照することを、強くお勧めします。
技術レベル : 100
できる!C#で非同期処理(Taskとasync-await)
パターンでわかる! .NET Coreの非同期処理
こちらも、あえて上に持ってきておきます。.NET Conf 2019 meetup in AICHIで登壇した時のスライドです。
.NET Core 3.0の登場で、C# 8.0と組み合わせた非同期処理が完成の域に達したと考え、Taskの登場から現在に至るまでの経過と、最低限知っておけば困らないポイントを凝縮して解説しました。
非同期処理の実装にこれから取り組む方、非同期処理が分からなくて悩んでいる方、全体を俯瞰したい方、最新の事情をキャッチアップしたい方にお勧めします。本記事ではセッションビデオも公開しているので、合わせて参照すればより理解が進むと思います。
技術レベル:200~400
元記事: パターンでわかる! .NET Coreの非同期処理
これからの「async/await」の話をしよう
「これからの「async/await」の話をしよう」は、名古屋Geekbarで登壇した時のプレゼンです。非同期処理実装の基礎を解説しています。この前身に「いまさら恥ずかしくてasyncをawaitした 」がありますが、改訂しているので本稿を参照すればOKです。
技術レベル:200~300
オリジナルスライド:これからの「async-await」の話をしよう.pptx
いまさら恥ずかしくてasyncをawaitした – 第9回まどべんよっかいち (初版)
async/await ダークサイド is 何
「async/await ダークサイド is 何」は、第10回まどべんよっかいちで登壇した時のプレゼンです。非同期処理実装での落とし穴を解説する、「これからの「async/await」の話をしよう」の続編です。
技術レベル:300~400
オリジナルスライド:async-awaitダークサイドis何
コマンドラインプログラムで非同期処理ってどう書くの?
コマンドラインプログラムで非同期処理をどのように実現するのかを解説しています。
技術レベル:300
データバインディングと非同期
「データバインディングと非同期」は、C# Advent Calendar 2014に参加して書いた記事です。XAMLのデータバインディング・MVVM環境と、そこに非同期処理をどのように実装するかという課題の解説です。
技術レベル:200~400
データバインディングと非同期 – C# Advent Calendar 2014
Async訪ねて3000里
「Async訪ねて3000里」は、C# 5.0で導入された非同期メソッドのDeep-Diveな記事です。.NET上で非同期メソッドを呼び出してから、Windowsのカーネルモードを経由して、デバイスにI/Oが発行され、結果が非同期で返却される過程を網羅しています。何故、スレッド並列化ではなく、非同期駆動する必要があるのかが読み取ってもらえれば幸いです。
# 注意:本稿は初心者向けではありません
技術レベル:500
目次
Async訪ねて3000里 (1): ユーザーモードのターン
Async訪ねて3000里 (2): ファイルシステム・パーティションマネージャ・物理ディスクデバイスドライバ
Async訪ねて3000里 (3): ハードウェア割り込みとDPC
Async訪ねて3000里 (4): I/Oの完了とAPC
Async訪ねて3000里 (5): TaskCompletionSourceでTaskの継続へ
Async訪ねて3000里 (6): I/O完了ポートによるワーカースレッドの運用
.NET非同期処理(async-await)を制御する、様々な方法
async-awaitベースの非同期処理を制御する方法をまとめました。
- Taskベースのワーカースレッド生成
- 他の非同期I/Oと連携してタスクを制御する方法
- TaskとLINQを応用して、多量の計算を安全に並列実行させる方法
- Taskを使っていない非同期処理をTask化する方法
- 非同期処理のキャンセルの実現方法
- WinRT・ユニバーサルWindowsアプリケーション(UWP)での非同期処理とTaskの連携方法
技術レベル:200~400
.NET非同期処理(async-await)を制御する、様々な方法
.NET非同期処理(async-await)と例外の制御
Taskクラスとasync-awaitを使用して非同期処理を記述する場合の、例外にまつわるあれこれをまとめました。
- 表面上は殆ど変らない
- 現実の動作
- タスクコンテキストとスレッドコンテキスト
- スタックウォーク
- 処理されない例外
技術レベル:300~450
継続飛行
「継続」とは何か、を、自分が経験してきたソフトウェアの知見を元に考えてみるシリーズです(現在連載執筆中)。
技術レベル:200~400
continuatioN Linking
継続渡しスタイル(Continuation Passing Style)の話に絡めて、.NET TaskとF# Asyncのシームレスな相互運用を行うネタの発表内容です。
元記事(解説あり): continuatioN Linking – NL名古屋
Async deepdive before de:code
de:code 2016の前夜祭である、Japan ComCamp meets de:codeで登壇した時のスライドです。
一般的に、async-awaitを使った非同期プログラミングを行う理由付けを、Windowsのメッセージポンプ(又はUIスレッド)との協調を行わなければならないという理由から展開しますが、このスライドでは純粋にパフォーマンスの観点から、非同期プログラミングの重要性にアプローチしました。主に「Async訪ねて3000里」や、過去私が解説してきた事の要約で構成されています。
技術レベル:400~500
.NET非同期処理で例外を安全に対処する
.NET非同期処理で、例外に対応する基本的な記述方法や、安全に例外を処理する方法を、わかりやすく掘り下げています。例えば、async voidメソッドで例外を安全に扱う方法を知っていますか?
技術レベル:200~300