タスクのキャンセルで例外が発生する
2023-12-24 14:47:01
質問
タスクについて読んだところでは、次のコードは例外を投げずに現在実行中のタスクをキャンセルする必要があります。私は、タスク キャンセルの全体のポイントは、スレッドを中止することなくタスクに停止するように丁寧に "ask" することであるという印象を受けました。
次のプログラムからの出力は。
例外をダンプする
[OperationCanceledException](オペレーションキャンセルドエクセプション
最後に計算された素数をキャンセルして返します。
キャンセル時に例外が発生しないようにしたいと考えています。どのようにしたらこれを達成できますか?
void Main()
{
var cancellationToken = new CancellationTokenSource();
var task = new Task<int>(() => {
return CalculatePrime(cancellationToken.Token, 10000);
}, cancellationToken.Token);
try
{
task.Start();
Thread.Sleep(100);
cancellationToken.Cancel();
task.Wait(cancellationToken.Token);
}
catch (Exception e)
{
Console.WriteLine("Dumping exception");
e.Dump();
}
}
int CalculatePrime(CancellationToken cancelToken, object digits)
{
int factor;
int lastPrime = 0;
int c = (int)digits;
for (int num = 2; num < c; num++)
{
bool isprime = true;
factor = 0;
if (cancelToken.IsCancellationRequested)
{
Console.WriteLine ("Cancelling and returning last calculated prime.");
//cancelToken.ThrowIfCancellationRequested();
return lastPrime;
}
// see if num is evenly divisible
for (int i = 2; i <= num/2; i++)
{
if ((num % i) == 0)
{
// num is evenly divisible -- not prime
isprime = false;
factor = i;
}
}
if (isprime)
{
lastPrime = num;
}
}
return lastPrime;
}
どのように解決するのですか?
この行で明示的にExceptionを投げています。
cancelToken.ThrowIfCancellationRequested();
タスクを優雅に終了させたいのであれば、単にこの行を削除する必要があります。
一般的には、潜在的に余分なコードを実行することなく、現在の処理を確実に中止するための制御メカニズムとして、これを使用します。また、タスクの終了を確認するために
ThrowIfCancellationRequested()
と機能的に同等であるためです。
if (token.IsCancellationRequested)
throw new OperationCanceledException(token);
を使う場合
ThrowIfCancellationRequested()
を使うと、タスクは次のようになります。
int CalculatePrime(CancellationToken cancelToken, object digits) {
try{
while(true){
cancelToken.ThrowIfCancellationRequested();
//Long operation here...
}
}
finally{
//Do some cleanup
}
}
また
Task.Wait(CancellationToken)
はトークンがキャンセルされた場合、例外を投げます。このメソッドを使用するには、Wait 呼び出しをラップして
Try...Catch
ブロックで囲む必要があります。
関連
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】OnCollisionEnter2Dが実行されない?
-
[解決済み] プロミス型タスクでStartを呼び出してはいけない。
-
[解決済み] 例外がスローされたことを確認するためにAssertを使用するにはどうすればよいですか?
-
[解決済み] 非同期Task<T>メソッドを同期的に実行するにはどうしたらいいですか?
-
[解決済み] async/await - タスクとvoidをいつ返すか?
-
[解決済み] タスクとスレッドの違いは何ですか?
-
[解決済み】C#で例外をキャッチして再スローする理由とは?
-
[解決済み】Task<T>の完了をタイムアウトで非同期に待つ
-
[解決済み】UIスレッドでのタスク継続について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み] 2つのリストを結合する
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み] CancellationTokenプロパティを使用するには?