Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  17:29[Войти] | [Зарегистрироваться]
Ответ на вопрос № 22432

17-05-2004 10:00
Здравствуйте!
Как перехватить необработанную исключительную ситуацию, возникшую в потоке (не в главном)?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

20-05-2004 11:45
to Kate:
Попробуйте использовать подмену обработчика исключений:

..........

type
  P_EXCEPTION_POINTERS = ^ EXCEPTION_POINTERS;

function MainFilter(P: P_EXCEPTION_POINTERS): integer; stdcall;
begin
  Result := 0; // показывать системный диалог
  // обработка возникших исключений
  case P.ExceptionRecord.ExceptionCode of
    EXCEPTION_ACCESS_VIOLATION:
      begin
      end;
    EXCEPTION_DATATYPE_MISALIGNMENT:
      begin
      end;
    else
      begin
        // можно данные скинуть в лог файл
        MessageBox(0, 'MainFilter','Error', MB_OK );
        Result := 1; // не показывать системный диалог
      end;
  end;
end;

Перед созданием потока произвести подмену обработчика:

begin
  ......
  SetUnhandledExceptionFilter(@MainFilter);
  TYourThread.Create(False);
  .....
end;

Успехов в трудном деле ....

19-05-2004 09:25
Kate, я перестаю понимать, чего вы хотите. Как обрабатываются исключения в главной нити, вы, судя по всему, хорошо представляете, и знаете, что никакого чуда в OnException нет. Вы также не хуже меня знаете, что VCL работает только в основной нити, а обработка исключений в вашей нити целиком на вашей совести. Если исключение, возникшее в нити, не снято, обработкой исключения начинает заниматься операционная система, а у неё свои взгляды на то, как его нужно обрабатывать. Например, в линии NT система прежде всего заботится о том, чтобы не нарушить работу других программ, поэтому с той программой, которая сгененрировала исключение, система особо не церемонится - сама, мол, виновата. И как бы вы ни старались, запретить системе перехватывать любые исключения можно только одним способом - поместить весь код целиком в try/except. И в неглавной нити за вас это никто не сделает. Весь вопрос только в том, как вы это оформите. Можно даже сделать у объекта нити событие, которое возникает, когда управление передаётся в главный Except. Можно даже сделать так, чтобы при наступлении этого события вызывался тот же обработчик, что и для Application.OnException. Только это всё придётся писать самостоятельно. Если вы ищете готовые средства, должен вас разочаровать - их нет.

19-05-2004 09:05 | Сообщение от автора вопроса
Антону Григорьеву:
Не придирайтесь к словам. Под необработанным исключением я, разумеется, подразумевала необработанное программистом исключение. И как работает Application.OnException я тоже не вчера узнала. И ненормальным его никто не называл. Он абсолютно нормален, но только для главного потока. Из нити в него исключения не передаются. Вообще говоря, если в нити возникло исключение, и оно не обработано (программистом), то поток просто завершает свою работу. Но не всегда! Иногда (и кто бы знал, при каком стечении обстоятельств это происходит) выдается сообщение об ошибке. Главный поток и остальные нити шуршат, как ни в чем не бывало, а эта зараза ждет, когда я "ОК" нажму. Так вот от этой неприятности и хочется избавиться.

18-05-2004 19:16
Для RIVco:
Сначала выучите матчасть, прежде чем меня просвещать. Специально для тех, кто в танке, повторяю: тот код, который пишет программист, VCL заключает в try/except, и когда возникает исключение, не обработанное этим кодом, управление передаётся в этот except, откуда и происходит вызов OnException. На всякий случай повторяю ещё раз: вызов OnException есть результат выполнения блока except, но не того, который написан автором программы, а того, который содержится в VCL. Именно это я и сказал в своём предыдущем посте. И это не противоречит результатам вашего эксперимента. А чтобы не быть голословным, советую вам заглянуть в модуль Forms и посмотреть, во-первых, код метода TApplication.HandleException, который вызывает OnException, а во-вторых, TApplication.WndProc, из которого вызывается HandleException, и убедиться, что этот вызов сделан изнутри блока except. Так что это я вам должен желать успехов в деле, которое для вас оказалось и в самом деле трудным.

А вообще, картина получается нерадостная. Сначала вы посоветовали использовать OnException, не заметив, что речь в вопросе идёт не о главном потоке и что Kate уже написала, что Application.OnException ей не подходит. Затем вы прокомментировали мой ответ - и опять не в тему. Может, в следующий раз, перед тем как написать ответ, вы всё-таки хотя бы чуть-чуть подумаете?

18-05-2004 17:58
Григорьеву Антону:
try except - это как раз и есть обработанное исключение и из блока except вы не получите выполнения Application.OnException, а вот когда нет этого блока и есть необработанное исключение.
Application.OnException возникает когда исключение не обработано.

Простой пример на форме 2 кнопки (их обработчики с небольшим отличем друг от друга)
(вот все листинги примера):

------------ Project1 ---------------
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas';

{$R *.RES}

begin
  GlobalExp := TGlobalExp.Create;
  Application.OnException := GlobalExp.HandleProc;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
------------ end Project1 ---------------

------------ Unit1 ---------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    raise Exception.Create('Block Except');
  except
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  raise  Exception.Create('No Block');
end;

end.
------------ end Unit1 ---------------

------------ Unit2 ---------------
unit Unit2;

interface

uses SysUtils,Dialogs;

type
  TGlobalExp = class
  public
    procedure HandleProc(Sender: TObject; E: Exception);
  end;

var
  GlobalExp: TGlobalExp;
implementation

{ TGlobalExHandler }

procedure TGlobalExp.HandleProc(Sender: TObject; E: Exception);
begin
  MessageDlg('Main Except'#13#10 + E.Message, mtInformation, [mbOk], 0);
end;

end.
------------ end Unit2 ---------------

Григорьеву Антону: По вашему ответу диалог будет показан при выполнении блока try except (нажатие на кнопку 1), а показывается диалог при не обработанном исключении (нажатие на кнопку 2).

Успехов в трудном деле ...

18-05-2004 16:31
И возвращаясь к сути вопроса, try/except - это обработанная исключительная ситуация, и здесь все понятно. А как с необработанными-то быть? Неужели нет нормальных механизмов?

А Application.OnException, по-вашему, как работает? Внутри объекта Application стоит вызов вашего кода, обрамлённый try/except. И когда возникает необработанное исключение и управление передаётся в блок except, из него вызывается событие OnException. Так что прежде чем обзывать какие-то механизмы ненормальными, вы бы разобрались с тем, как "нормальные" работают.

18-05-2004 10:25
Сделайте глобальный обработчик событий:
в файле проекта:

begin
  .........
  GlobalExp := TGlobalExp.Create;
  Application.OnException := GlobalExp.HandleProc;
  ..........
  Application.Run;
end;

и распишите класс обработки исключений с нужной вам реакцией

  TGlobalExp = class
  public
    procedure HandleProc(Sender: TObject; E: Exception);
  end;

procedure TGlobalExp.HandleProc(Sender: TObject; Exp: Exception);
begin
  if Exp is ...... then
    begin
    end
  else
    ..........
end;

При такой обработке все исключения не обработанные в модулях будут обрабатываться на вашем классе TGlobalExp.

Успехов в трудном деле ...

18-05-2004 06:33 | Сообщение от автора вопроса
Теоретически, конечно, можно и большой try/except сделать. На практике, откинув логику программы и возможность кому-либо во всем этом разобраться, придется поместить энное количество модулей примерно по 1000 строк каждый в одну ну очень большую процедуру. Даже представить себе этого не могу. И возвращаясь к сути вопроса, try/except - это обработанная исключительная ситуация, и здесь все понятно. А как с необработанными-то быть? Неужели нет нормальных механизмов?

17-05-2004 16:12
А если весь код Execute заключить в один большой try-except?

17-05-2004 13:50 | Сообщение от автора вопроса
Конечно, программа работает не из под Delphi. Круглосуточно и не первый месяц. Мне просто нужен аналог события TApplication.OnException для нити.

17-05-2004 13:04
А сообщения среды отключены? По умолчанию Delphi в любом случае сначала выдаёт сообщение, а потом проболжает работу программы, если программа запущена из-под Delphi.

17-05-2004 12:53 | Сообщение от автора вопроса
Все так и сделано. Только, если ошибка возникает во внешнем модуле и она не обработана, то try/except в Thread.Execute не помогает, поскольку сначала появляется сообщение об ошибке, а уж по нажатию "ОК" возвращается в Execute. Блоков try/except по программе полно, но, видимо, недостаточно. Ошибка появляется редко, и отловить ее затруднительно. Поэтому и нужно перехватывать все необработанные исключительные ситуации.

17-05-2004 10:18
По хорошему это должен делать менеджер нитей(Thread, не Stream), но если говорить о простой реализации, то в Thread.Execute достаточно сделать try/except, а обрабатку данных выполнять не внутри этой процедуры, а во внешнем модуле. Так и локализовать проблему проще и создавать новые нити с обработчиками легче.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Кто съел Красную шапочку?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования