問題タブ [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.

0 投票する
3 に答える
4800 参照

c# - 非同期タスク、キャンセル、および例外

私は現在、ライブラリ API の非同期部分をTasks で適切に公開する方法を学んでいます。これにより、顧客がより簡単に、より使いやすくなります。私は、スレッドプールでスケジュールされていないa をラップするアプローチTaskCompletionSourceを採用することにしました(ここのインスタンスでは、基本的に単なるタイマーであるため、とにかく不要です)。Taskこれは問題なく機能しますが、キャンセルは今のところ少し頭痛の種です.

この例は、トークンにデリゲートを登録する基本的な使用法を示していますが、私の場合よりも少し複雑ですTaskCanceledExceptionドキュメントには、単に戻ってタスクのステータスを に切り替えるか、 (タスクの結果が になる) をRanToCompletionスローするだけで問題ないと書かれています。ただし、例は、に渡されたデリゲートを介して開始されるタスクにのみ関連するか、少なくとも言及しているようです。OperationCanceledExceptionCanceledTaskFactory.StartNew

私のコードは現在(おおよそ)次のとおりです。

(実行中に結果はなく、例外の可能性もありません。ライブラリのより複雑な場所ではなく、ここから開始することを選択した理由の 1 つです。)

現在のフォームでは、 を呼び出すとTrySetCanceled、タスクが返されるのを待っている場合TaskCompletionSourceは常に が返されます。私の推測では、これは通常の動作であり (そうであることを願っています)、キャンセルを使用する場合は呼び出しを/で囲む必要があります。TaskCanceledException trycatch

を使用しない場合TrySetCanceled、最終的には終了コールバックで実行され、タスクは正常に終了したように見えます。しかし、ユーザーが正常に終了したタスクとキャンセルされたタスクを区別したい場合は、それTaskCanceledExceptionを保証することの副作用ですよね?

私がよく理解していなかったもう 1 つの点:ドキュメントによると、キャンセルに関係するものであっても例外はすべてAggregateExceptionTPL によってラップされます。ただし、私のテストでは、TaskCanceledExceptionラッパーなしで常に直接取得します。ここに何かが欠けていますか、それとも文書化が不十分なだけですか?


TL;DR:

  • タスクが状態に移行するには、Canceled常にそれに対応する例外が必要であり、ユーザーはそれを検出できるように非同期呼び出しをtry/で囲む必要があります。catch
  • ラップTaskCanceledExceptionされていない状態で投げられることも予想され、正常であり、私はここで何も悪いことをしていませんか?
0 投票する
2 に答える
691 参照

c# - デッドロックの原因は何ですか?

私のコードでデッドロックの問題に直面しています。ありがたいことに、以下の例で問題を再現できました。通常の .Net Core 2.0 コンソール アプリケーションとして実行します。

私が期待するのは、次のような完全なシーケンスです。

ただし、実際のシーケンスはThread.Join呼び出しで停止します。

MainAsync最後に、本体に小さな遅延を挿入すると、すべてがうまくいきます。なぜ (どこで) デッドロックが発生するのか?

注: 元のコードでは、 a のSemaphoreSlim代わりに aを使用して解決しましたがTaskCompletionSource、まったく問題はありません。問題がどこにあるかを理解したいだけです。