Есть словарь делегатов. Из под BackgroundWorker.DoWork из этого словаря выбирается нужный делегат и вызывается. В функции делегата происходит исключение. Если исключение перехватить внутри функции и пробросить дальше через throw, то все работает нормально, исключение ловит и catch внутри функции делегата и catch в DoWork. Если catch из функции делегата убрать, то исключение куда-то пропадает и до catch'а в DoWork не доходит. Кто-нибудь сталкивался с такой проблемой? Это что в дотнете есть такая мегабага?
Framework 2.0
Здравствуйте, 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 во вновь созданном потоке обработано не будет. Вы поймете почему, если вспомните, что поток имеет свой независимый путь исполнения. Решение состоит в добавлении обработки исключений непосредственно в метод потока
Здравствуйте, 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 не доходит.
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