[解決済み] タスクで例外をキャッチする最適な方法は何ですか?
2023-05-01 09:34:03
質問
と
System.Threading.Tasks.Task<TResult>
で、私は投げられる可能性のある例外を管理しなければなりません。そのための最良の方法を探しています。今のところ、私はキャッチされない例外をすべて
.ContinueWith(...)
もっと良い方法はないかと考えています。あるいは、それが良い方法であるかどうかさえも。
public class BaseClass
{
protected void ExecuteIfTaskIsNotFaulted<T>(Task<T> e, Action action)
{
if (!e.IsFaulted) { action(); }
else
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
/* I display a window explaining the error in the GUI
* and I log the error.
*/
this.Handle.Error(e.Exception);
}));
}
}
}
public class ChildClass : BaseClass
{
public void DoItInAThread()
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew<StateObject>(() => this.Action())
.ContinueWith(e => this.ContinuedAction(e), context);
}
private void ContinuedAction(Task<StateObject> e)
{
this.ExecuteIfTaskIsNotFaulted(e, () =>
{
/* The action to execute
* I do stuff with e.Result
*/
});
}
}
どのように解決するのですか?
使用している言語のバージョンによって、2つの方法があります。
C# 5.0 およびそれ以上
を使用することができます。
async
と
await
というキーワードを使うことで、かなりの部分を簡略化することができます。
async
と
await
の使用を簡略化するために、言語に導入されました。
タスク並列ライブラリ
を使う必要がないようにするためです。
ContinueWith
を使う必要がなくなり、トップダウン方式でプログラミングを続けることができるようになります。
このため、単純に
try
/
catch
ブロックを使って、このような例外をキャッチします。
try
{
// Start the task.
var task = Task.Factory.StartNew<StateObject>(() => { /* action */ });
// Await the task.
await task;
}
catch (Exception e)
{
// Perform cleanup here.
}
上記のメソッドをカプセル化した
は
を使用するには
async
キーワードが適用されるので
await
.
C# 4.0 およびそれ以下
例外を処理するには
ContinueWith
オーバーロード
から値を受け取る
TaskContinuationOptions
列挙
というように
// Get the task.
var task = Task.Factory.StartNew<StateObject>(() => { /* action */ });
// For error handling.
task.ContinueWith(t => { /* error handling */ }, context,
TaskContinuationOptions.OnlyOnFaulted);
は
OnlyOnFaulted
のメンバは
TaskContinuationOptions
の列挙は、継続が
だけ
が実行されることを示します。
もちろん、2つ以上の
ContinueWith
を呼び出すことができます。
// Get the task.
var task = new Task<StateObject>(() => { /* action */ });
// For error handling.
task.ContinueWith(t => { /* error handling */ }, context,
TaskContinuationOptions.OnlyOnFaulted);
// If it succeeded.
task.ContinueWith(t => { /* on success */ }, context,
TaskContinuationOptions.OnlyOnRanToCompletion);
// Run task.
task.Start();
関連
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] C#の[Flags]Enum属性の意味とは?
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] C#で文字を繰り返し表示する最適な方法
-
[解決済み] 私のインターフェースがTaskを返さなければならない場合、操作不要の実装を持つための最良の方法は何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない