問題タブ [cancellationtokensource]
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# - CancellationTokenSource.Cancel() が Moq で呼び出されたことを確認する
次のような条件文があります。
ここで、PermanentCancellation は CancellationTokenSource 型です。
_view のモックでこれをどのように設定すればよいか疑問に思っています。これまでのすべての試みは失敗しました:(そして、Googleで例を見つけることができません。
任意のポインタをいただければ幸いです。
c# - モックされたメソッドを検証するには、これもモックされている特定のCancellationTokenSouceを使用します
特定のCancellationTokenSourceがメソッド呼び出しの実際のパラメーターとして使用されていることを確認しようとしています。
以下は私のテストです:
エラーメッセージは次のとおりです。
少なくとも1回はモックでの呼び出しが必要ですが、実行されませんでした。x => x.SetupCsvFileVerification(.entity.Object、(Object).source.Object.Token)セットアップが構成されていません。
sourceで表されるクラスは次のとおりです。
単体テストを実行すると、ctsにはTempCsvFileVerificationCancellationの値が割り当てられます。sourceのTokenプロパティは、Source.Tokenを返します。私が間違ったことをしたことについて途方に暮れています。
任意のポインタ/支援をいただければ幸いです。
ありがとう
編集
python - Python スレッド化でキャンセル トークンをシミュレートする
一度に実行されるタスクの数を制限するタスク キューを Python で作成しました。Queue.Queue
これは、キューに入れることができるアイテムの数を制限するのではなく、一度に取り出すことができるアイテムの数を制限するためとは少し異なります. これは引き続き unbounded を使用してジョブを実行しますが、スレッドの数を制限するためQueue.Queue
に a に依存しています。Semaphore
タスク キューを明示的に停止しない限り、Python インタープリターは永久に実行されます。これは私が思っていたよりもはるかにトリッキーです。メソッドを見ると、キューにフラグ、セマフォ、ノーオペレーション コールバックstop
を設定していることがわかります。または でコードがブロックされる可能性があるため、最後の 2 つの部分が必要です。基本的に、ループが発生する可能性があるように、これらを強制的に通過させる必要があります。canceled
release
put
Semaphore
Queue
このコードは機能します。このクラスは、何千ものタスクを並行して実行しようとするサービスを実行する場合に役立ちます。マシンのスムーズな実行を維持し、アクティブなスレッドが多すぎることを OS が叫ぶのを防ぐために、このコードは同時に存在するスレッドの数を制限します。
以前に C# で同様のコードを書いたことがあります。そのコードを特定の切り詰めたものにしたのは、.NET には、CancellationToken
ほぼすべてのスレッド クラスが使用する a と呼ばれるものがあるためです。ブロッキング操作があるときはいつでも、その操作はオプションのトークンを取ります。親タスクがキャンセルされると、そのトークンでブロックされている子タスクもすぐにキャンセルされます。これは、セマフォを解放したり値をキューに入れたりして「偽装」するよりも、はるかにクリーンな終了方法のように思えます。
Pythonでこれを行う同等の方法があるかどうか疑問に思っていましたか? 非同期イベントのようなものではなく、スレッドを使用したいのは間違いありません。1 つが最大サイズで、もう 1 つが最大サイズでない2 つの s を使用して同じことを達成する方法があるかどうか疑問に思っていますが、Queue.Queue
キャンセルの処理方法はまだわかりません。
c# - 複数のイベントをキューに入れてキャンセルするにはどうすればよいですか?
次のメソッドをトリガーするイベントがあるとします。
元のオブジェクトはName
文字列としての名前とCancellationTokenSource
. 私が理解したところでは、それを検知してManualResetEvent.WaitOne()
電話をかければ、キャンセルが完了するのを待つことができます。処理する新しいイベントが 1 つしかない場合、これはうまくいくようです。ただし、現在のプロセスのキャンセル中にこのイベントを複数回トリガーすると、代わりに両方のイベントが同時に実行されるようになりました。望ましい結果は、最新のイベントより前のすべてのイベントがキャンセルされ、処理が最新のイベントで実行されることです。ManualResetEvent.Set()
cts.IsCancellationRequested == true
どうすればこれを機能させることができますか?私は正しい軌道に乗っていますか?この質問への回答に役立つ追加情報があればお知らせください。
c# - CancellationTokenSourceをDownloadStringTaskAsyncメソッドにアタッチして、非同期呼び出しをキャンセルするにはどうすればよいですか?
非同期とawaitメソッドを使用してWebClientを使用してリンクを呼び出すサンプル例を作成しました。次に、非同期呼び出しのキャンセル機能もアタッチします。しかし、CancellationTokenSourceトークンを取得して、このキャンセルトークンにDownloadStringTaskAsyncをアタッチすることはできません。次の私のコードは誰でもこれを達成する方法を教えてもらえますか?
[キャンセル]ボタンがcts.Cancelを呼び出すと、DownloadStringTaskAsync呼び出しはキャンセルされません。キャンセルボタンが非同期呼び出しをキャンセルできないのはなぜですか?
c# - CancellationToken が CancellationTokenSource と異なるのはなぜですか?
クラスCancellationToken
に加えて.NET 構造体が導入された理由の根拠を探しています。API の使用方法CancellationTokenSource
は理解していますが、そのように設計されている理由も理解したいと考えています。
つまり、なぜ私たちは持っているのですか:
次のように直接渡す代わりにCancellationTokenSource
:
これは、トークンを渡すよりもキャンセル状態のチェックが頻繁に行われるという事実に基づくパフォーマンスの最適化ですか?
それで、それCancellationTokenSource
は と update を追跡できCancellationTokens
、各トークンのキャンセルチェックはローカルフィールドアクセスですか?
どちらの場合も、ロックのない volatile bool で十分であることを考えると、なぜそれが高速になるのかはまだわかりません。
ありがとう!
c# - CancellationTokenSource.Cancel は ObjectDisposedException をスローします
を所有するクラスがありCancellationTokenSource
ます。
現在のトークンを使用して、長時間実行される操作を開始しています。
私のオブジェクトも「リサイクル」をサポートする必要があります。生まれ変わりを考えてください。前の人生で開始されたすべての長時間実行操作はキャンセルする必要があります。
この場合、ソースに対して and を呼び出しCancel
、Dispose
新しいトークン ソースを発行します。
このメソッドは、トークンを期限切れにするときと、このクラスを破棄するときの 2 つの場所で呼び出します。
メソッドからObjectDisposedException
呼び出したときにエラーが発生することがあります。ドキュメントには次のように記載されています。_tokenSource.Cancel ()
Dispose
のすべてのパブリック メンバーとプロテクト メンバー
CancellationTokenRegistration
はスレッド セーフであり、複数のスレッドから同時に使用できます。例外は、 に対する他のすべての操作が完了Dispose
した場合にのみ使用する必要があります。CancellationTokenRegistration
現時点ではどうすればよいかわかりません。?でラップCancelToken
します。
競合状態は正確にどこで発生し、それを軽減する方法は?lock
常に同じスレッドで呼び出されることPrepareForReuse
は確かですが、別のスレッドで呼び出される可能性があります。Dispose
これが役立つ場合、.NET Framework ではなく Mono を実行していますが、キャンセル トークンに関しては同じセマンティクスを持つ必要があると確信しています。
c# - 大量の HTTP 要求をキャンセルすると、キャンセルが長時間ブロックされるのはなぜですか?
バックグラウンド
1 つの特定のホストからのコンテンツを使用してバッチ HTML ページ処理を実行するコードがあります。を使用して多数 (~400) の同時 HTTP リクエストを作成しようとしますHttpClient
。同時接続の最大数はによって制限されていると思われるServicePointManager.DefaultConnectionLimit
ため、独自の同時実行制限を適用していません。
HttpClient
すべての要求をusingに非同期で送信した後、andTask.WhenAll
を使用してバッチ操作全体をキャンセルできます。操作の進行状況はユーザー インターフェイスを介して表示でき、ボタンをクリックしてキャンセルを実行できます。CancellationTokenSource
CancellationToken
問題
CancellationTokenSource.Cancel()
約 5 ~ 30 秒間ブロックする呼び出し。これにより、ユーザー インターフェイスがフリーズします。メソッドがキャンセル通知用に登録したコードを呼び出しているために、これが発生したと思われます。
私が考えたこと
- 同時 HTTP 要求タスクの数を制限します。
HttpClient
すでに過剰なリクエスト自体をキューに入れているように見えるため、これを回避策と考えています。 CancellationTokenSource.Cancel()
非 UI スレッドでメソッド呼び出しを実行する。これはうまくいきませんでした。他のほとんどのタスクが完了するまで、タスクは実際には実行されませんでした。async
メソッドのバージョンがうまく機能すると思いますが、見つかりませんでした。また、UIスレッドでメソッドを使うのにも向いている印象です。
デモンストレーション
コード
出力
キャンセルが長時間ブロックされるのはなぜですか? また、私が間違っていること、または改善できることはありますか?
asp.net-mvc - アクションの実行をキャンセル
フィルターと 2 つのボタン (生成とキャンセル) を含むページがあります。そのため、Generate ボタンをクリックすると、Results アクションに移動します。[キャンセル] ボタンをクリックすると、コードとデータベースで以前のリクエストをキャンセルしたいと思います。
いくつかのコード (.NET 4.0、MVC 4 を使用)
ResultsController.cs:
ResultsRepository.cs
したがって、期待される結果: レポート生成要求をキャンセルすると、データは表示されません。
主な質問: メソッド tokenSource.Cancel() を使用してリクエストをキャンセルできますか? または、ThrowIfCancellationRequested() メソッドを使用する必要があります (どこで?)
c# - CancellationTokenSourceがメインスレッドでのみキャンセルされるCancellationTokenの競合状態
いくつかの結果を生成するボタンがあるWinformsアプリケーションについて考えてみます。ユーザーがボタンを2回押すと、最初のリクエストをキャンセルして結果を生成し、新しいリクエストを開始する必要があります。
以下のパターンを使用していますが、競合状態を防ぐためにコードの一部が必要かどうかはわかりません(コメントアウトされた行を参照)。
知らせ:
CancellationTokenSource
メインスレッドでのみキャンセルします。CancellationToken
継続では、元のタスクと同じものを使用します。
次の一連のイベントが可能かどうか疑問に思っています。
- ユーザーが「結果の生成」ボタンをクリックします。初期タスクt1が開始されます。
- ユーザーは「結果の生成」ボタンをもう一度クリックします。Windowsメッセージはキューに送信されますが、ハンドラーはまだ実行されていません。
- タスクt1が終了します。
- TPL startは、継続を開始する準備をします(
まだキャンセルCancellationToken
されていないため)。タスクスケジューラは、作業をWindowsメッセージキューに送信します(メインスレッドで実行するため)。 - 2回目のクリックのgenerateResultsButton_Clickが実行を開始し、
CancellationTokenSource
がキャンセルされます。 - 継続作業が開始され、トークンがキャンセルされなかったかのように動作します(つまり、UIに結果が表示されます)。
だから、私は質問が要約すると思います:
作業がメインスレッドに投稿されると(を使用してTaskScheduler.FromCurrentSynchronizationContext()
)、TPLCancellationToken
はタスクのアクションを実行する前にメインスレッドでをチェックしますか、またはそれが起こっているスレッドでキャンセルトークンをチェックしてから、作業をに投稿しますSynchronizationContext
?