問題タブ [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 と volatile ブール値
終了することを通知するために、 揮発性のブール値フィールドよりもCancellationTokenSourceを使用する利点はありますか?Task
c# - CancellationToken をキャンセルする方法
タスクを開始すると、他のタスクが開始されます。そのツリーを考えると、いずれかのタスクが失敗した場合、操作全体の結果は役に立たなくなります。キャンセルトークンの利用を検討しています。驚いたことに、トークンには「CancelThisToken()」メソッドがありません...
CancellationTokenのみを所有している場合、どうすればキャンセルできますか?
c# - CancellationTokenSource.Cancel への呼び出しは返されません
への呼び出しが返されない状況がありCancellationTokenSource.Cancel
ます。代わりに、Cancel
が呼び出された後 (および戻る前) に、キャンセルされるコードのキャンセル コードで実行が続行されます。キャンセルされたコードが待機可能なコードをその後呼び出さない場合、最初に呼び出した呼び出し元Cancel
は制御を取り戻すことはありません。これは非常に奇妙です。Cancel
キャンセルのリクエストを記録するだけで、キャンセル自体に関係なくすぐに返信できると思います。Cancel
が呼び出されているスレッドが、キャンセルされている操作に属するコードを実行することになり、呼び出し元に戻る前に実行されるという事実Cancel
は、フレームワークのバグのように見えます。
これがどのようになるかは次のとおりです。
コードの一部があります。これを「ワーカー コード」と呼びましょう。これは、何らかの非同期コードを待機しています。簡単にするために、このコードが Task.Delay で待機しているとしましょう。
/li>
「ワーカー コード」が呼び出される直前にTask.Delay
、スレッド T1 で実行されます。継続 (「await」の後の行または catch 内のブロック) は、一連の要因に応じて、後で T1 または他のスレッドで実行されます。
- もう 1 つのコードがあります。これを「クライアント コード」と呼びましょう
Task.Delay
。このコードは を呼び出しますcancellationToken.Cancel
。への呼び出しCancel
は、スレッド T2 で行われます。
の呼び出し元に戻ることで、スレッド T2 が続行することを期待しますCancel
。catch (OperationCanceledException)
また、スレッド T1 または T2 以外のスレッドですぐに実行されるコンテンツが表示されることを期待しています。
次に何が起こるかは驚くべきことです。スレッド T2 では、Cancel
が呼び出された後、 内のブロックですぐに実行が続行されることがわかりcatch (OperationCanceledException)
ます。そして、それCancel
はまだコールスタックにある間に起こります。への呼び出しCancel
がキャンセルされたコードによってハイジャックされたかのようです。このコール スタックを示す Visual Studio のスクリーンショットを次に示します。
より多くのコンテキスト
実際のコードが何をするかについて、もう少し説明があります。リクエストを蓄積する「ワーカー コード」があります。リクエストは、いくつかの「クライアント コード」によって送信されています。数秒ごとに「ワーカー コード」がこれらのリクエストを処理します。処理された要求はキューから削除されます。ただし、「クライアント コード」は、要求をすぐに処理する必要があるポイントに達したと判断することがあります。これを「ワーカー コード」に伝えるために、「Jolt
ワーカー コード」が提供するメソッドを呼び出します。Jolt
「クライアント コード」によって呼び出されるメソッドはTask.Delay
、ワーカー コードのメイン ループによって実行される a をキャンセルすることによって、この機能を実装します。ワーカーのコードはTask.Delay
キャンセルされ、既にキューに入れられていたリクエストの処理に進みます。
実際のコードは最も単純な形式に分解されており、コードはGitHubで入手できます。
環境
この問題は、コンソール アプリ、Universal Apps for Windows のバックグラウンド エージェント、および Universal Apps for Windows Phone 8.1 のバックグラウンド エージェントで再現できます。
この問題は、コードが期待どおりに機能し、への呼び出しCancel
がすぐに返される Windows 用のユニバーサル アプリでは再現できません。
c# - タスク C# を停止/破棄/キャンセルする
Googleドライブ/ドロップボックス/ ftpなどのさまざまなリポジトリからDLLをインポートして、Windowsサービス内にDLLを展開しようとしています...
しかし、新しい DLL をインスタンス化する前に、以前に実行していたインスタンスをシャットダウンする必要があります。
これにはタスクとリフレクションを使用しています。
実行時に DLL をインスタンス化するタスクをキャンセルする方法がわかりません(インスタンス化された dll は長時間実行されるアプリケーション サンプル ファイル ウォッチャーであるため..)
質問: アプリケーションが新しい dll を検出し、このタスク コードを使用してそれを実行しようとする前に、タスク t をキャンセルしたいです。
EDIT キャンセルトークンコードが壊れていたので削除しました。キャンセル トークンを含む実際のコードを次に示します。
私の考えは、インスタンス化コンテキストを保持していたタスクを何らかの方法でキャンセルして破棄できれば、アセンブリが解放され、アセンブリを更新して、タスクを介して再度インスタンス化できるようになるというものでした。
私はどこかで間違っていることを知っています。親切に説明してください。
編集
私は assemblyDomain.DoCallBack(delegate) に大きな期待を寄せていました。しかし、エラーが発生します。これは、バグをスローするコードのトーンダウン バージョンです。
エラー :
アセンブリ 'AppDomain、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null' の 'AppDomain.Program+<>c__DisplayClass2' と入力すると、シリアル化可能としてマークされていません。
スタックトレース :
注意してください:私はシリアライズ可能としてインポートするアセンブリのクラスProgramをマークしました
更新しました :
動的にプルされたアセンブリのコード