我有一個應用程序被配置爲捕獲任何在app.config中ThrowUnobservedTaskExceptions enabled =「true」的未觀測任務異常。處理UnobservedTaskException
我有一個庫類(Class1)需要在它的構造函數中啓動一個異步任務,但是在某些引發異常的場景中,當Class1的實例被丟棄時我進入UnobservedTaskException錯誤(因爲那個任務永遠不會期待已久的)。
我解決了這個問題,通過在構造函數中附加ContinueWith並處理異常(通過訪問任務的Exception屬性),並將TaskContinuationOptions設置爲OnlyOnFaulted,並且完美地工作。
現在我遇到的問題是這個異步任務(我在構造函數中初始化)也在等待這個類的方法作爲驗證檢查,以確保任務完成後繼續執行方法中的其餘代碼。如果在實例化我的類(Class1)後調用了此方法,並且它引發了錯誤,則我已附加的ContinueWith會被執行並處理異常。我不想要這種行爲。如果在方法內部等待時發生錯誤,我希望它拋出異常。
我只希望unobservedtaskexceptions只針對這種情況處理(不針對整個應用程序) - 當Class1被初始化並且沒有方法被調用時,以及如果任務拋出異常,我會在ContinueWith中處理它。我不希望ContinueWith中的代碼在方法內等待此任務時執行,並且如果拋出。
下面是將提供更清晰的代碼。請讓我知道是否有辦法實現這一目標。
的Program.cs
using (Class1 c = new Class1())
{
c.ValidateInitializeAsync().Wait(); // I want this to throw. Only if this line is commented, I want the exception to be handled.
}
// The application needs to be run in Release mode in order for GC to dispose c and enter into the scenario I want
while (true)
{
Thread.Sleep(100);
GC.Collect();
GC.WaitForPendingFinalizers();
}
的Class1.cs
class Class1 : IDisposable
{
public Task initializeTask;
public Class1()
{
this.initializeTask = TaskHelper.InlineIfPossible(() => RunTask()).ContinueWith(t =>
{
Console.WriteLine(string.Format("Exception handled, {0}", t.Exception.HResult));
}, TaskContinuationOptions.OnlyOnFaulted);
}
public async Task ValidateInitializeAsync()
{
await this.initializeTask;
}
public async Task RunTask()
{
await Task.Run(() =>
{
Console.WriteLine("Running task...");
Task.Delay(5000).Wait();
throw new InvalidOperationException("exception occured");
});
}
public void Dispose()
{
Console.WriteLine("Class1 disposed.");
}
}
static class TaskHelper
{
static public Task InlineIfPossible(Func<Task> function)
{
if (SynchronizationContext.Current == null)
{
return function();
}
else
{
return Task.Run(function);
}
}
}