Если вы пытаетесь зарегистрировать все ошибки, убедитесь, что вы сохранили строку Task.WhenAll в своем коде, многие комментарии предполагают, что вы можете удалить ее и дождаться отдельных задач. Task.WhenAll действительно важна для обработки ошибок. Без этой строки вы потенциально оставляете свой код открытым для незаметных исключений.
var catTask = FeedCat();
var houseTask = SellHouse();
var carTask = BuyCar();
await Task.WhenAll(catTask, houseTask, carTask);
var cat = await catTask;
var house = await houseTask;
var car = await carTask;
Представьте, что FeedCat генерирует исключение в следующем коде:
var catTask = FeedCat();
var houseTask = SellHouse();
var carTask = BuyCar();
var cat = await catTask;
var house = await houseTask;
var car = await carTask;
В этом случае вы никогда не будете ждать houseTask или carTask. Существует 3 возможных сценария:
Вот ошибка, которую вы получите для случая (3):
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.HttpApplication.System.Web.Util.ISyncContext.Enter()
at System.Web.Util.SynchronizationHelper.SafeWrapCallback(Action action)
at System.Threading.Tasks.Task.Execute()
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.HttpApplication.System.Web.Util.ISyncContext.Enter()
at System.Web.Util.SynchronizationHelper.SafeWrapCallback(Action action)
at System.Threading.Tasks.Task.Execute()<---
Для случая ( 2) вы получите аналогичную ошибку, но с исходной трассировкой стека исключений.
Для .NET 4.0 и более поздних версий вы можете поймать ненаблюдаемые исключения, используя TaskScheduler.UnobservedTaskException. Для .NET 4.5 и более поздних ненаблюдаемых исключений по умолчанию пропущено исключение unobserved .NET 4.0 приведет к сбою вашего процесса.
Подробнее здесь: Обработка исключений задач в .NET 4.5
Теперь в случае строки это не так, потому что строка войдет в пул строк, а JVM сохранит объект для повторного использования. Итак, это означает, что некогда созданная строка будет «никогда» не собираться мусором?
blockquote>Во-первых, это только String литералы 1, которые получают автоматически интернирован / добавлен в пул строк. Строки, созданные приложением, не интернированы ... если ваше приложение явно не называет
String.intern()
.Во-вторых, на самом деле правила сбора мусора в пуле String такие же, как для других строк / другие объекты. Строки будут собирать мусор, если они когда-либо станут недоступными.
На практике объекты String, которые соответствуют строковым литералам обычно , не становятся кандидатами на сборку мусора. Это связано с тем, что имеется ссылка неявная ссылка на строковый объект в коде каждого метода, который использует литерал. Это означает, что String достижима до тех пор, пока метод может быть выполнен.
Однако это не всегда случай. Если литерал был определен в классе, который был динамически загружен (например, с помощью
Class.forName(...)
), тогда можно организовать, что класс разгружен . Если это произойдет, объект String для литерала будет недоступен и будет восстановлен, когда куча, содержащая интернированную строку, получит GC'ed.
1 - Неверно говорить, что все строковые литералы интернированы. Если строковый литерал появляется только в исходном коде в качестве подвыражения выражения константы (времени компиляции) ( JLS 15.28 ), то литерал не будет отображаться в файле «.class» в любой форме . Такой литерал не будет интернирован, потому что он не будет существовать во время выполнения.
Вы правы; строки в основном пуле никогда не будут GC'd.
Однако большинство строк не интернированы. Строковые литералы интернированы, а строки, переданные в String.intern()
, интернированы, но все остальные строки не интернированы и могут быть GC'd в норме.
new
, не будет интернирована. Объект String, представляющий строковый литерал , будет i> интернирован.
– Stephen C
22 August 2014 в 15:56