Jaster
Jaster

Reputation: 8579

TaskScheduler.UnobservedTaskException - High delay before raise

I am using a task based (TPL) threading model. When starting my application (WPF) I register TaskScheduler.UnobservedTaskException to display a Message.

However if an exception is raised (e.g.Task.Factory.StartNew(() => throw new Exception());) it takes quite a significant amount of time (3-10 seconds) before the UnobservedTaskException event is raised.

I want it to be raised immediatly (or at least very quick), any idea on what could be the case here?

Regards

Upvotes: 1

Views: 475

Answers (2)

Shahin Dohan
Shahin Dohan

Reputation: 6922

Async void methods always raise exceptions on the Dispatcher, so if you have a method returning a Task, you could wrap it in an async void method then await it.

I had to do this once because I had to call an async method in a property setter (There was a good reason for it which I'm not going to get into, but generally this is a bad idea)

private T _activeItem;
public T ActiveItem
{
    get => _activeItem;
    set => ActivateItemAsyncVoid(value);
}

private async void ActivateItemAsyncVoid(T item)
{
    await ActivateItemAsync(item);
}

public async Task ActivateItemAsync(T item, CancellationToken cancellationToken = default)
{
    // Do stuff
}

If I directly call ActivateItemAsync in the setter then I cannot await it, but this way I can await it.

Upvotes: 0

Bryan Crosby
Bryan Crosby

Reputation: 6554

This is because the finalizer for that thread has not run yet. Since this occurs with a Garbage Collection, this non-deterministic. Additionally, how does the CLR determine whether to throw it immediately or you wanted to check the task's result or call Wait() and observe the exception yourself?

If you enable Break on First Chance Exceptions, it will get thrown while debugging.

It will be propagated back to the joining thread, guaranteed. If you are using .NET 4.0, your process will terminate. If you are using .NET 4.5, it won't

Upvotes: 2

Related Questions