Reputation: 7110
I use a pattern including tasks in C# where I do
Task.Factory.StartNew( .something... )
.ContinueWith(t=> {
try{ t.Wait() }
catch(Exception ex) ...
});
if something
forexample includes WCF code or other exception throwing stuff. That way Im sure that the tasks have been waited for I dont get those finalizer exceptions and I can consistently log error messages.
Recently I have seen that t.Wait() throws ObjectDisposed exception. Is my pattern wrong or should I keep the continue with only on TaskContinuationOptions.NotOnRanToCompletion
.
Upvotes: 1
Views: 2373
Reputation: 8116
You can use the following TaskContinuationOptions to see how your Task finished.
var t = Task.Factory.StartNew(...)
(....)
t.ContinueWith(task => (..Ran to Completion.. + task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
t.ContinueWith(task => (..Handle Exception .. + task.Exception),
TaskContinuationOptions.OnlyOnFaulted);
t.ContinueWith(task => (.. Was cancelled..),
TaskContinuationOptions.OnlyOnCanceled);
Upvotes: 1
Reputation: 1063453
If the continuation is firing, it is pretty obvious that it has completed (one way or another); there is no need to Wait()
on something that has finished. Just check how it finished (completion, cancellation (.IsCanceled
), exception (.IsFaulted
)), and access the result (.Result
) if appropriate.
The ObjectDisposedException
sounds like the notorious WCF "feature", where-by the Dispose()
in WCF can throw the above (which is annoying). There are various ways proposed to wrap WCF to handle this, but this is unrelated to the task API. WCF thus swallows the actual error, and surfaces ObjectDisposedException
. There are several stackoverflow questions that address this.
Upvotes: 3