マルチスレッド環境では、書き込み可能なリソースへの同時アクセスを考慮する必要があります。一般的なアプローチは、Monitor
またはその省略形lock
を使用することです。
Task
はThread
とは異なる抽象化レベルにあります。タスクはそれ自体のスレッドで実行される場合があります(ログによると、アプリケーションで実行されます)が、これは保証されていません。たとえば、 タスクとスレッドの違いは何ですか? :
待機している値がファイルシステム、データベース、またはネットワークからのものである場合、スレッドが他の要求を処理できるときにデータを待つ必要はありません。代わりに、タスクは準備ができたときに値を受け取るためにコールバックを登録する場合があります。
つまり、そのようなTask
は、他の実行中のコードとThread
を何らかの形で共有しています(私はそれがどのように機能するか詳細に理解していないことを認めなければなりません。現在、私は、 「有名」DoEvents
)。
したがって、Monitor
はそれらを区別できません。また、Monitor
は再入可能であるため、両方にリソースへのアクセスを許可します。つまり、Monitor
は失敗します。
それにもかかわらず、Threads
を使用した例では、通常Monitor
を使用します。 Monitor
がTask
で安全であることをどのように確認できるかを確認したいと思います(または、Task
がThread
自体)。
ですから、Monitorがタスクに対して安全であることをどのように確認できるか(または、タスクが独自のスレッドで実行されていることをどのように確認できるか)を質問したいと思います。
あなたはしません。非同期操作でMonitor
を使用するべきではありません。正確にできないこれを保証します(可能であってもしたくない)。
解決策は、非同期のコンテキストで適切に機能するように設計されたさまざまな同期メカニズムを使用することです。たとえば、スレッドアフィニティを使用する必要はありません。また、クリティカルセクションへのアクセスを同期的に待機するのではなく、それら自体を非同期にする必要があります。
答えは、SemaphoreSlim
を使用することです。これには、WaitAsync
を使用できるawait
メソッドがあります。従来のクリティカルセクションがあると想定すると、セマフォを設定して1つの同時操作のみを許可できます。これを使用して、スレッドがセマフォへのアクセスを取得すると、非同期操作を開始し、alsoがセマフォへのアクセスを試みる他のことを実行します。アクセスはありません。また、セマフォを取得したスレッドとは別のスレッドからセマフォを解放するときに問題が発生しないことも意味します。