Когда вызывается Application.Run - весь вызвавший поток отдаёт на выполнение обработки событий. Может кто то объяснить, почему тут исключение не ловится:
{$reference System.Windows.Forms.dll}
begin
var f := new System.Windows.Forms.Form;
var main_thr := System.Threading.Thread.CurrentThread;
f.Shown += (o, e)->
begin
writeln(System.Threading.Thread.CurrentThread=main_thr);//true, то есть это тот же поток
Sleep(100);
raise new Exception;
end;
try
System.Windows.Forms.Application.Run(f);
except
writeln('got exception');//эта строчка не вызывается, в место этого оболочке передаётся исключение
end;
end.
с Application.Run() всё не просто. Там может быть так, что графическая оболочка программы (именно с ней работает Application.Run()) является корневым, т.е. основным потоком программы. Если Вы пытаетесь обработать исключение, то предполагается наличие родительского потока, что невозможно по определению.
Ссылку дать не могу, так как это моё мнение. Но вот то, что Application.Run работает крайне необычно я заметил уже давно. Этот метод запускает приложение с главной формой, переданной в качестве параметра. Мне кажется, если исключение происходит там(на форме), то его попросту невозможно обработать. Если исключение в дочерней форме, например в файловом диалоге, то да, но этим занимается главная форма. В графических программах всё гораздо сложнее, чем в консольных. Я с ними года 2 разбирался. А если представить, что в WPF…
begin
var t1 := Arr(1, 2, 3);
var t2 := Arr(1, 2, 3);
if t1 = t2 then Println('t1=t2')
else Println('t1<>t2');
var u1 := (1, 2, 3);
var u2 := (1, 2, 3);
if u1 = u2 then Println('u1=u2')
else Println('u1<>u2')
end.
Хотелось бы понять, что тут сравнивается - содержимое ссылок на созданные объекты? И тогда, поскольку кортежи одинаковы, обе ссылки адресуются к одному и тому же объекту? Или все намного мудрее?
Это лишь в простейшей. Да и то, В ОТЛАЖЕННОЙ. А мы помним известную фразу о том, что “Тестирование может доказать наличие ошибок в программе, но никогда не докажет их отсутствия”. Или это я помню, а Вы - нет? ))))
Я то помню, только вот что даст исключение простому пользователю? Особенно если нет отладочной информации и проект с закрытым исходным кодом? Я понимаю, что Вы не верите, что эта проверка замедляет программу, но я уже приводил пример. И опять таки, 2,5 раза.
Как это - не верю? Любая проверка замедляет, это очевидно. Другой вопрос, что PascalABС.NET - он не для этого. Супероптимизацию при математических вычислениях и работе с массивами дает только Фортран и с этим нужно смириться, нравится Вам это, или нет. Ну вот просто он именно ради этого делался. Отрицать, что нечто специализированное хуже универсального - это не очень логично.
Наверно, можно. Но вот нужно ли тратить на это время и силы, ответить могут только разработчики. Например, в части оптимизации указателей уже ответили: “нет”.
А можно ведь и с другой стороны зайти. Почему бы не сделать директиву компилятора, отключающую проверку на выход за границы массива? А её реализация будет использовать указатели, так как .NET иначе не умеет.
Т.е. дать возможность пользователю развалить свой код? Индекс вышел за границу, адресовались неизвестно куда, случайно попали с модификацией в какую-то ссылку… дальше что? " Ах-вах, шайтан какой, совсем этот Паскаль крышей поехал ! " ? Не знаю, мне это неинтересно, а “заднее слово” - оно, как обычно, за разработчиками.
Почему? Я же сказал, что эта возможность подключается ДИРЕКТИВОЙ, а по умолчанию отключена. Если пользователь уверен в том, что программа работает правильно, он может подписать сверху директиву и ускорить программу.
Вы не замечаете, что все время пытаетесь предложить сделать Паскаль таким, каким он будет удобен лично Вам ? Несмотря на явно сдержанную в этом отношении позицию разработчиков.