Это последующая деятельность после this question. Я также прочитал статью "Tasks and Unhandled Exceptions" Стивена Туба, и я думаю, что я понимаю, как работают задачи и исключения и что означает «наблюдаемая задача». Я, однако, не могу понять, как сказать, наблюдался ли Task
или нет. Возможно ли это вообще без использования отражения?Как узнать, была ли «Наблюдаемая задача»?
Я хотел бы позаимствовать @Noseratio's code в качестве примера:
static async void Observe(Task task)
{
await task;
}
// ...
var taskObserved = false;
var task = DoSomething()
try
{
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
taskObserved = true;
return value + await task;
}
finally
{
if (!taskObserved)
Observe(task);
}
Если бы мы могли сказать, был ли соблюден задача, это можно было бы сделать проще и более удобным для чтения:
static async void Observe(Task task)
{
if (!task.WasObserved)
await task;
}
// ...
var task = DoSomething()
try
{
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
}
finally
{
Observe(task);
}
Спасибо, Стивен, я надеялся, что вы ответите. На самом деле меня интересует «наблюдаемый» (а не «ожидаемый») статус. Например, если «Task.Exception» был затронут и т. Д. У меня есть вопрос о вашем 1-м фрагменте кода, но не собирается ли это же исключение 2 раза? Итак, я собираюсь освободить фрейм стека за 1-й бросок? – avo
@avo: Если 'task' завершается в неисправном состоянии, вы не потеряете фрейм стека. Стек уже захвачен и помещен в объект 'Exception' в' task.Exception'. 'await' достаточно умен, чтобы сохранить захваченный стек одновременно. –
В идеале я бы хотел, чтобы все еще можно было распространять исключения из «DoSomethingElse» или «DoThirdThing», если любой из них выбрасывает «DoSomething». Однако «DoSomething» берет на себя эти исключения в этом случае. – avo