概要
Couchbase .NET SDKは、System.Threading.Tasks
名前空間のクラスを用いた「タスクベースの非同期パターン(TAP)」を使用して、るCouchbaseServerに対する非同期操作を実現します。同期操作のための固有のAPIはない代わりに、Task.Result
メソッドを使用して、すべてのタスクをブロッキング方式で同期的に実行できます。
.Netにおける非同期プログラミング、特に「タスクベースの非同期パターン(TAP)」に関する詳しい情報は、こちらのMicrosoftのドキュメントをご確認ください。
実装例による解説
Couchbase Serverへの接続
後述の全ての処理は、Cluster
オブジェクトで接続を開始し、バケットとコレクションをオープンするところから始まります。
var cluster = new Cluster("couchbase://localhost", new ClusterOptions()
.WithConnectionString("couchbase://localhost")
.WithCredentials(username: "user", password: "password")
.WithBuckets("travel-sample")
);
var bucket = await cluster.BucketAsync("default");
var collection = bucket.DefaultCollection();
await
を使用した非同期プログラミング
await
の利用は、非同期操作を行うための最も基本的な方法です。
var upsertResult = await collection.UpsertAsync("doc1",new {Name = "Ted", Age = 80});
using (var getResult = await collection.GetAsync("doc1"))
{
var person = getResult.ContentAs<dynamic>();
}
ここでは、例外処理は考慮していないことにご注意ください。
GetAsync
メソッドは、GetResult
を返します。そのGetResult
のContentAs
メソッドを使用して、戻り値を読み取ります。
Task.Result
を使用した同期プログラミング
上記で利用した同じメソッド(UpsertAsync
, GetAsync
)を同期的に呼び出すこともできます。その場合、次のように、Result
プロパティを使用します。
var upsertResult = collection.UpsertAsync("doc1",new {Name = "Ted", Age = 80}).Result;
using (var getResult = collection.GetAsync("doc1").Result)
{
var person = getResult.ContentAs<dynamic>();
}
上記の同期処理と同様のことを行う別の方法は、Task.GetAwaiter().GetResult()
のようにAwaiter
を明示的に呼び出すことです。
var upsertResult = collection.UpsertAsync("doc1",new {Name = "Ted", Age = 80}).GetAwaiter().GetResult();
using (var getResult = collection.GetAsync("doc1").GetAwaiter().GetResult())
{
var person = getResult.ContentAs<dynamic>();
}
Task.WhenAll
を使用して多数のタスクを同時に実行する
特定の状況では、多数のタスクの(実行順序のない)組み合わせを同時に実行したい場合があります。このようなバッチ処理を行うためには、Task.WhenAll
を使用します。
var tasks = new List<Task<IGetResult>>
{
collection.GetAsync("doc1"),
collection.GetAsync("doc2"),
collection.GetAsync("doc3"),
collection.GetAsync("doc4")
};
var results = await Task.WhenAll(tasks);
foreach (var getResult in results)
{
var doc = getResult.ContentAs<dynamic>();
//戻り値のドキュメントに対する処理
}
この例では、4つのドキュメントを非同期にフェッチし、全ての結果が返されるまで状態を一時停止します。次に、結果のリストをループして各ドキュメントを同期的に処理しています。
上述したように、非同期処理は、実行順序に関係のないタスクの組み合わせの実行という意味で、本質的にバッチ操作です。
下では、上とは少し異なる方法による実装例にコメントを附しています。
// Taskリストの初期化
var tasks = new List<Task>();
// 同期的にタスクを作成し、リストに格納(これらのタスクはまだスケジュールされていません)
for (var i = 0; i <100; i++)
{
var task = collection.GetAsync($"mykey-{i}");
tasks.Add(task);
}
// リスト中の全てのタスクの完了を待つ
await Task.WhenAll(tasks);
// リストから順次、結果を受け取る
foreach (var task in tasks)
{
var result = tasks.Result;
}
参考情報
Couchbase公式ドキュメント .NET SDK / Advanced Data Operations / Async & React APIs