6

エラーを処理するための継続的なタスクがあります。

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
var loadTask = Task<List<OrderItemViewModel>>.Factory.StartNew(() =>
{
       throw new Exception("derp");
});

var errorContinue = loadTask.ContinueWith(t =>
    {
        MainViewModel.RemoveViewModel(this);
    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler);

継続がヒットしましたが、数秒後、アプリケーションで次のエラーが発生しました。

タスクの例外は、タスクの待機またはそのExceptionプロパティへのアクセスのいずれによっても観察されませんでした。その結果、監視されていない例外がファイナライザスレッドによって再スローされました。

これはuiSchedulerに関連していますか?同様の質問の解決策は、基本的に私が行っていることです 。タスクの例外は、タスクの待機またはそのExceptionプロパティへのアクセスのいずれによっても観察されませんでした。その結果、観察されなかった例外は

4

1 に答える 1

6

例外を実際に処理する(または少なくとも観察する)必要があります。

var errorContinue = loadTask.ContinueWith(t =>
{
    // Observe/acknowledge the exception.  
    // You can use t.Wait(), which throws, or just grab the exception
    var exception = t.Exception; 
    MainViewModel.RemoveViewModel(this);
}, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler);

これは、TPLでの例外処理に関するドキュメントの次の行が原因です。

例外を伝播するタスクを待機しない場合、またはそのExceptionプロパティにアクセスしない場合、タスクがガベージコレクションされるときに、.NET例外ポリシーに従って例外がエスカレーションされます。

あなたの場合、継続はありますが、実際に「例外を待つ」ことも、その例外プロパティにアクセスすることもありません。(あなたが投稿した関連する質問で)私の答えが機能する理由は、継続を通過したタスクで実際にExceptionプロパティを使用しているためです。

于 2012-09-08T01:18:24.203 に答える