C#でasync/await
の新しい非同期パターン/言語サポートを使用する新しいフレームワークの多くのメソッドがあります。 Monitor.EnterAsync()
または現在のスレッドを解放する他のasync lock
メカニズムがない理由&はlock
が利用可能になるとすぐに戻りますか?Monitor.EnterAsyncのようなメソッドがない理由
私はこれが不可能であると仮定します。質問はなぜですか?
C#でasync/await
の新しい非同期パターン/言語サポートを使用する新しいフレームワークの多くのメソッドがあります。 Monitor.EnterAsync()
または現在のスレッドを解放する他のasync lock
メカニズムがない理由&はlock
が利用可能になるとすぐに戻りますか?Monitor.EnterAsyncのようなメソッドがない理由
私はこれが不可能であると仮定します。質問はなぜですか?
.Netのサプライ品は、基になるネイティブオブジェクトの周りのラッパーを管理します。
現在、非同期ロックを実装するネイティブ同期プリミティブはありません。だから.Netの実装者はゼロから実装する必要があります。これはそう簡単ではありません。
また、Windowsカーネルには「locking-delegation」の機能はありません。つまり、あるスレッドでロックをロックしたり、所有権を別のスレッドに渡したりすることはできません。難しい
私の意見では、第3の理由は、非同期IO、ロックフリーアルゴリズム、データ構造のような非ブロック技術をブロックしたくない場合、より哲学的なものです。アプリケーションのボトルネックが重い競合であり、その周囲にロックオーバーヘッドがある場合、非同期ロックを必要とせずに、アプリケーションを別の形式で再設計できます。
*モニターはCRITICAL_SECTIONのラッパーです*は真です。サポートする権限のあるリソースを追加できますか? –
Joe duffyによる同時プログラミングはこれを呼び出す**物理的には、モニタにはWindows CRITICAL_SECTIONは含まれていませんが、動作しているかのように動作します。** Pgno:272 –
私の回答を再編集させてください –
Monitor.Enter
を呼び出すと、現在のスレッドは、渡されたオブジェクトのロックを取得したいという問題があると思います。したがって、Monitor.EnterAsync
をどのように実装するのか自分自身に尋ねるべきですか?最初の素朴な試みは次のようになります。
public async Task EnterAsync(object o)
{
await Task.Run(() => Monitor.Enter(o));
}
しかし、それは明らかに何を期待しませんが、ロックはスレッドによって獲得されるため、呼び出し元のスレッドがその新しいTask
のために開始しません。
これで、待ってからロックを獲得できるようにするメカニズムが必要になります。しかし、私は現在、これが確実に動作するように、どのスレッドも他のスレッドがロックを獲得しないようにする方法を考えることはできません。
これらは、ちょうど私の2セント(それはあまりにも長い間なかった場合は、コメントとして投稿しているでしょう)です。より詳細な知識を持つ方から、より啓発的な答えをお待ちしております。
デフォルトによる.NET には、非同期モニターはありませんが、Stephen Clearyは待つ/非同期を使用した場合、同期の問題を扱う大きなライブラリAsyncExを持っています。
AsyncMonitor
クラスがあり、これはあなたが探しているものとほとんど同じです。 GitHubまたはNuGet packageから入手できます。
使用例:
私はこれが不可能であると仮定 - 疑問は、なぜでしょうか?
これは、まだ完了していない可能性があります。
現在、BCLの唯一の非同期互換同期プリミティブは、SemaphoreSlim
です。これは、セマフォまたは単純な相互排除ロックとして機能します。
私は、Stephen Toub's blog post seriesに大まかに基づいて、AsyncMonitor
that I wroteを基本としています。セマンティクスはBCL Monitor
とわずかに異なります。特に、再帰的ロック(reasons I describe on my blogの場合)は許可されません。
私はこの質問をモニターについて知っていますが、非同期操作を提供するいくつかの同期プリミティブがあります:https://msdn.microsoft.com/en-us/library/hh462723.aspx –
これは絶対に可能です! '' Monitor''は基本的な型であるため、既存の '' Monitor''クラスには改造されていません。これはかなり洗練されたケースです(実際には、本当にそれが必要です)。実装については、https://github.com/StephenCleary/AsyncEx/wiki/AsyncMonitorを参照してください。 –
実装することは可能ですが、実際に試して実際に使用すると問題が発生します。 http://stackoverflow.com/questions/7612602/why-cant-i-use-the-await-operator-within-the-body-of-a-lock-statement – vcsjones