Я создал следующую программу на С#:
namespace dispose_test
{
class Program
{
static void Main(string[] args)
{
using (var disp = new MyDisposable())
{
throw new Exception("Boom");
}
}
}
public class MyDisposable : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
}
Когда я запускаю это с помощью dotnet run
, я вижу следующее поведение:
- Windows: текст исключений, записанный на консоль, "Disposed" напечатан ~ 20 секунд позже, выходы программы.
- Linux: текст исключений, записанный на консоль, программа немедленно завершает работу. "Disposed" никогда не писал.
Задержка в Windows раздражает, но факт, что Dispose() вообще не вызван на Linux, вызывает беспокойство. Это ожидаемое поведение?
РЕДАКТИРОВКА Разъяснения/дополнения из беседы ниже:
- Это не относится к
using/Dispose()
, что является частным случаемtry/finally
. Поведение также обычно происходит сtry/finally
- блокfinally
не запускается. Я обновил название, чтобы отразить это. - Я также проверил выполнение
Dispose()
, записав файл в файловую систему, чтобы убедиться, что проблема не связана с отключением stdout от консоли до запускаDispose()
в случае необработанной исключение. Поведение было одинаковым. -
Dispose()
вызывает вызов, если исключение поймано в любом месте приложения. Это когда он полностью не обрабатывается приложением, что такое поведение происходит. - В Windows длительный разрыв не связан с задержкой компиляции. Я начал отсчет времени, когда текст исключения был записан на консоль.
- Мой оригинальный эксперимент выполнял
dotnet run
на обеих платформах, что означает отдельные компиляции, но я также попытался сделатьdotnet publish
в Windows и напрямую запустить вывод на обеих платформах с тем же результатом. Единственное различие заключается в том, что при запуске непосредственно в Linux текст "Aborted (core dumped)" записывается после текста исключения.
Сведения о версии:
-
dotnet --version
→ 1.0.4. - Компиляция в netcoreapp1.1, работающая на .NET Core 1.1.
-
lsb-release -d
→ Ubuntu 16.04.1 LTS