問題タブ [taskcompletionsource]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 非同期タスク、キャンセル、および例外
私は現在、ライブラリ API の非同期部分をTask
s で適切に公開する方法を学んでいます。これにより、顧客がより簡単に、より使いやすくなります。私は、スレッドプールでスケジュールされていないa をラップするアプローチTaskCompletionSource
を採用することにしました(ここのインスタンスでは、基本的に単なるタイマーであるため、とにかく不要です)。Task
これは問題なく機能しますが、キャンセルは今のところ少し頭痛の種です.
この例は、トークンにデリゲートを登録する基本的な使用法を示していますが、私の場合よりも少し複雑ですTaskCanceledException
。ドキュメントには、単に戻ってタスクのステータスを に切り替えるか、 (タスクの結果が になる) をRanToCompletion
スローするだけで問題ないと書かれています。ただし、例は、に渡されたデリゲートを介して開始されるタスクにのみ関連するか、少なくとも言及しているようです。OperationCanceledException
Canceled
TaskFactory.StartNew
私のコードは現在(おおよそ)次のとおりです。
(実行中に結果はなく、例外の可能性もありません。ライブラリのより複雑な場所ではなく、ここから開始することを選択した理由の 1 つです。)
現在のフォームでは、 を呼び出すとTrySetCanceled
、タスクが返されるのを待っている場合TaskCompletionSource
は常に が返されます。私の推測では、これは通常の動作であり (そうであることを願っています)、キャンセルを使用する場合は呼び出しを/で囲む必要があります。TaskCanceledException
try
catch
を使用しない場合TrySetCanceled
、最終的には終了コールバックで実行され、タスクは正常に終了したように見えます。しかし、ユーザーが正常に終了したタスクとキャンセルされたタスクを区別したい場合は、それTaskCanceledException
を保証することの副作用ですよね?
私がよく理解していなかったもう 1 つの点:ドキュメントによると、キャンセルに関係するものであっても例外はすべてAggregateException
TPL によってラップされます。ただし、私のテストでは、TaskCanceledException
ラッパーなしで常に直接取得します。ここに何かが欠けていますか、それとも文書化が不十分なだけですか?
TL;DR:
- タスクが状態に移行するには、
Canceled
常にそれに対応する例外が必要であり、ユーザーはそれを検出できるように非同期呼び出しをtry
/で囲む必要があります。catch
- ラップ
TaskCanceledException
されていない状態で投げられることも予想され、正常であり、私はここで何も悪いことをしていませんか?
c# - デッドロックの原因は何ですか?
私のコードでデッドロックの問題に直面しています。ありがたいことに、以下の例で問題を再現できました。通常の .Net Core 2.0 コンソール アプリケーションとして実行します。
私が期待するのは、次のような完全なシーケンスです。
ただし、実際のシーケンスはThread.Join
呼び出しで停止します。
MainAsync
最後に、本体に小さな遅延を挿入すると、すべてがうまくいきます。なぜ (どこで) デッドロックが発生するのか?
注: 元のコードでは、 a のSemaphoreSlim
代わりに aを使用して解決しましたがTaskCompletionSource
、まったく問題はありません。問題がどこにあるかを理解したいだけです。