Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
574 views
in Technique[技术] by (71.8m points)

.net - Why doesn't my process terminate when Task has unhandled exception?

I am building a Windows Service with .NET 4.0.

I have various unhandled exceptions thrown in Tasks, but they do not terminate my process as the MSDN documentation states (Parallel Tasks - see Unobserved Task Exceptions).

"If you don't give a faulted task the opportunity to propagate its exceptions (for example, by calling the Wait method), the runtime will escalate the task's unobserved exceptions according to the current .NET exception policy when the task is garbage-collected."

It behaves like this even when I use the most simple invokation of a task:

Task.Factory.StartNew(() => { throw new Exception(); } 

The service keeps on running fine when that is called.

According to the docs, the finalizer of the Task will rethrow the exception once the Task is GC'd but this does not appear to happen. MSDN states repeatedly that normal ".NET exception policy" results in process termination.

Why doesn't this terminate my app? The only thing I can think is there is somehow a reference to the task held somewhere (is it the lambda??)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From Essential C# 4.0, page 715, the following might help you out:

The unhandled exception during the Task's execution will be suppressed until a call to one of the task completion members: Wait(), Result,Task.WaitAll(), or Task.WaitAny(). Each ot these members will throw any unhandled exceptions that occurred within the task's execution.

Quite a few ways of handling exceptions are available. Have a look at MSDN here.

In answer to your comment, another quote from the same book explains why some exceptions are not propagated:

Although relatively rare, one of the exceptions for the general rule (of bubbling up) happens to be on Task. [..] Any Task-based exceptions thrown from the finalization queue during application exit will go suppressed. The behavior is set this way because frequently the effor to handle such an exception it too complex [...]

To overcome this, one way to do this elegantly is to create an exception handler task and to use ContinueWith to follow up after your task runs. You can then use parentTask.IsFaulted and gracefully crash, even in the event the exception is thrown in the finalization queue during application exit.

Tip: use the the flag OnlyOnFaulted to have this task run only when an exception occurs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...