web-dev-qa-db-ja.com

タスクでモニター(ロック)を使用するのはいつ安全ですか?

マルチスレッド環境では、書き込み可能なリソースへの同時アクセスを考慮する必要があります。一般的なアプローチは、Monitorまたはその省略形lockを使用することです。

TaskThreadとは異なる抽象化レベルにあります。タスクはそれ自体のスレッドで実行される場合があります(ログによると、アプリケーションで実行されます)が、これは保証されていません。たとえば、 タスクとスレッドの違いは何ですか?

待機している値がファイルシステム、データベース、またはネットワークからのものである場合、スレッドが他の要求を処理できるときにデータを待つ必要はありません。代わりに、タスクは準備ができたときに値を受け取るためにコールバックを登録する場合があります。

つまり、そのようなTaskは、他の実行中のコードとThreadを何らかの形で共有しています(私はそれがどのように機能するか詳細に理解していないことを認めなければなりません。現在、私は、 「有名」DoEvents)。

したがって、Monitorはそれらを区別できません。また、Monitorは再入可能であるため、両方にリソースへのアクセスを許可します。つまり、Monitorは失敗します。

それにもかかわらず、Threadsを使用した例では、通常Monitorを使用します。 MonitorTaskで安全であることをどのように確認できるかを確認したいと思います(または、TaskThread自体)。

4
Bernhard Hiller

ですから、Monitorがタスクに対して安全であることをどのように確認できるか(または、タスクが独自のスレッドで実行されていることをどのように確認できるか)を質問したいと思います。

あなたはしません。非同期操作でMonitorを使用するべきではありません。正確にできないこれを保証します(可能であってもしたくない)。

解決策は、非同期のコンテキストで適切に機能するように設計されたさまざまな同期メカニズムを使用することです。たとえば、スレッドアフィニティを使用する必要はありません。また、クリティカルセクションへのアクセスを同期的に待機するのではなく、それら自体を非同期にする必要があります。

答えは、SemaphoreSlimを使用することです。これには、WaitAsyncを使用できるawaitメソッドがあります。従来のクリティカルセクションがあると想定すると、セマフォを設定して1つの同時操作のみを許可できます。これを使用して、スレッドがセマフォへのアクセスを取得すると、非同期操作を開始し、alsoがセマフォへのアクセスを試みる他のことを実行します。アクセスはありません。また、セマフォを取得したスレッドとは別のスレッドからセマフォを解放するときに問題が発生しないことも意味します。

6
Servy