2016-04-18 8 views
2

私はここで読む:あなたが明示的にバックエンドのスレッド・プール内の同じスレッドで非同期/のawait、タスクはしません「タイムスライス」を使用しない限り、Tasksでlock()を使用するのは安全ですか?

.NET async, can a single thread time-slice between tasks?

。これは保証されていますか?あるいは、TPLの現在の実装の副作用ですか?保証されない場合は

、それはlock()を使用して問題を引き起こす:

はリリースする前に、完全なSERIALPORTトランザクション(メッセージを送信および受信、またはタイムアウト)にlocksメソッドにアクセスする2つのタスクを考えてみましょう。同じスレッド上でタイムスライスが発生し、SerialPortアクセスが十分に遅い場合、lockは、技術的には同じスレッド上にあるため、両方の呼び出しを処理することができません。限り、あなたは(の一部)を行い何もしないよう

+0

通常、外部呼び出しの動作が何であれロックされていないので、実際のコードには問題はないはずです... –

+1

はい、タスクスケジューラ(カスタム)は、利回りまたはリターン。物理的には、同じスレッドで2つのコード本体を同時に実行することはできません。 –

+1

この質問は、 'async' /' await'コードには当てはめられていない生のTPLコードに関するものです。エラーを受け取ると 'await'の周りに' lock'を置くことはできません。 '' await '演算子は使用できませんロックステートメントの本体に「そうしようとしています。 –

答えて

1

はい、あなたのコードは、別のスレッド(awaitTask.Run()Task.ContinueWith()Thread、...)上で実行され、それがlockまたは別のスレッドを使用しても安全ですベースの同期メカニズム。カスタムTaskScheduler(例えばTaskScheduler.FromCurrentSynchronizationContext())を持っていて、何とかそのスケジューラは、あなたのTaskはまだ(例えばApplication.DoEvents()のようなもの)を実行している間に、よりTask Sを実行しようとしますならば

一つの可能​​な例外はあります。その場合、Taskはまだ別のスレッドには移動しませんが、もう1つのスレッドTaskが同じスレッドで実行されている間に一時停止する可能性があります。しかし、この状況は非常にまれです。

関連する問題