Пропажа исключения
От: Undying Россия  
Дата: 04.08.11 04:03
Оценка:
Есть словарь делегатов. Из под BackgroundWorker.DoWork из этого словаря выбирается нужный делегат и вызывается. В функции делегата происходит исключение. Если исключение перехватить внутри функции и пробросить дальше через throw, то все работает нормально, исключение ловит и catch внутри функции делегата и catch в DoWork. Если catch из функции делегата убрать, то исключение куда-то пропадает и до catch'а в DoWork не доходит. Кто-нибудь сталкивался с такой проблемой? Это что в дотнете есть такая мегабага?

Framework 2.0
Re: Пропажа исключения
От: rumatavz  
Дата: 04.08.11 07:39
Оценка:
А можно минимальный код, воспроизводящий проблему?
Re: Пропажа исключения
От: Aspid.net  
Дата: 04.08.11 08:00
Оценка:
Здравствуйте, Undying, Вы писали:


U>Есть словарь делегатов.

....
Это что в дотнете есть такая мегабага?
U>Framework 2.0

Это окей. BackgroundWorker запускает работу в новом потоке.
Здесь есть про обработку исключений в различных потоках
Автор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/



try/catch здесь фактически совершенно бесполезны, и NullReferenceException во вновь созданном потоке обработано не будет. Вы поймете почему, если вспомните, что поток имеет свой независимый путь исполнения. Решение состоит в добавлении обработки исключений непосредственно в метод потока

Re[2]: Пропажа исключения
От: Undying Россия  
Дата: 04.08.11 08:29
Оценка:
Здравствуйте, Aspid.net, Вы писали:

AN>Это окей. BackgroundWorker запускает работу в новом потоке.

AN>Здесь есть про обработку исключений в различных потоках
Автор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/


AN>

AN>try/catch здесь фактически совершенно бесполезны, и NullReferenceException во вновь созданном потоке обработано не будет. Вы поймете почему, если вспомните, что поток имеет свой независимый путь исполнения. Решение состоит в добавлении обработки исключений непосредственно в метод потока


Не в этом проблема.

Есть код:


        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
                  ...
          try
          {
            loaders[args.Type](args, cancelDelegate, out cancelled);
             }
          сatch (Exception ex)
          {
                    TraceHlp2.WriteException(ex, "Loader.worker_DoWork");
          }
        }


Который в результате вызова делегата хранящегося в loaders вызывает:

   private void DoWorkOnData(LoadingArgs args, CancelCallback cancelDelegate, out bool cancelled)
   {
      try
      {
            List<byte> data =
              context.GetData(args.TimeStamp, args.DeviceID, args.DataEncoding);
      }
      catch
      {
        throw;
      }
   }


Естественно, что worker_DoWork вызывается в отдельном потоке, но DoWorkOnData вызывается в том же потоке, что и worker_DoWork.

Если context.GetData бросил исключение, то если в DoWorkOnData есть выделенное, то все работает нормально, в catch'е worker_DoWork исключение ловится. Если же catch-throw из DoWorkOnData убрать, то исключение до catch'а worker_DoWork не доходит.
Re[3]: Пропажа исключения
От: rumatavz  
Дата: 04.08.11 09:36
Оценка: 1 (1)
    internal class Program
    {
        private static BackgroundWorker _worker;

        private static void Main()
        {
            _worker = new BackgroundWorker();
            _worker.DoWork += DoWork;
            _worker.RunWorkerAsync();
            
            //Спим, иначе background thread помрет
            Thread.Sleep(1000);
        }

        private static void DoWork(object obj, EventArgs e)
        {
            try
            {
                Foo foo = FooImpl;
                foo("Bar");
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Catched");
            }
        }

        private static List<byte> FooImpl(string s)
        {
//            try
//            {
                throw new ApplicationException();
//            }
//            catch (Exception ex)
//            {
//                throw;
//            }
            
        }

        private delegate List<byte> Foo(string s);
    }


У меня это работает без проблем.
Framework 2.0. С# ISO2
Re[4]: Пропажа исключения
От: Undying Россия  
Дата: 04.08.11 10:03
Оценка:
Здравствуйте, rumatavz, Вы писали:

R>У меня это работает без проблем.


На простом примере мне воспроизвести не удалось. Делегаты оказались не причем, если вызов делегата заменить на прямой вызов функции ничего не меняется.
Re[5]: Пропажа исключения
От: rumatavz  
Дата: 04.08.11 10:43
Оценка:
А приложение виндовое оконное?
Re[6]: Пропажа исключения
От: Undying Россия  
Дата: 04.08.11 11:55
Оценка:
Здравствуйте, rumatavz, Вы писали:

R>А приложение виндовое оконное?


Да.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.