Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку.
Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
Re: Исключения в потоках.
От:
Аноним
Дата:
28.06.08 13:48
Оценка:
Здравствуйте, Аноним, Вы писали:
всё может разрулиться событиями с помощью EventArgs передавай свой ексепшн.
Здравствуйте, Аноним, Вы писали:
А>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
Можно передавать в поток SynchronizationContext того потока, который следует известить об исключении.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Исключения в потоках.
От:
Аноним
Дата:
28.06.08 15:19
Оценка:
Интерессно, а можно какой- нибудь простой примерчик с использованием контекстов синхронизации, например на такой сценарий:
OnButtonClicked() // STA
{
try
{
Evaluate();
}
catch(Exception exc)
{
// Мы никогда сюда не попадем (*)
}
}
public void Evaluate() //функция обарачивает поток
{
ThreadStart ts = delegate
{
try
{
//........
trow new Exception();
}
catch(Exception exc)
{
// ловим исключение, о котором нужно оповестить поток из STA (*)
}
};
Thread thr = new Thread(ts);
thr.IsBackground = true;
thr.Start();
thr.Join();
}
Здравствуйте, Аноним, Вы писали:
А>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку. А>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
Например, использовать пару:
void xxxAsync() — для запуска
event yyy xxxCompleted — вытаскивать по завершению
в параметре завести поле, где можно передавать исключение если оно возникло в процессе выполнения:
class yyy : EventArgs
{
public Exception Exception;
public object Result;
}
Re[2]: Исключения в потоках.
От:
Аноним
Дата:
28.06.08 16:18
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>всё может разрулиться событиями с помощью EventArgs передавай свой ексепшн.
Тот же код возврата -- вид с боку. EventArgs может не проверятся...
Re[2]: Исключения в потоках.
От:
Аноним
Дата:
28.06.08 16:40
Оценка:
Здравствуйте, vioso, Вы писали:
V>Здравствуйте, Аноним, Вы писали:
А>>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку. А>>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
V>Например, использовать пару:
V>void xxxAsync() — для запуска V>event yyy xxxCompleted — вытаскивать по завершению
V>в параметре завести поле, где можно передавать исключение если оно возникло в процессе выполнения:
V>class yyy : EventArgs V>{ V>public Exception Exception; V>public object Result; V>}
Да, я думал об этом, но в таком сценарии тот же недостаток, что и у кодов возврата — EventArgs может не проверятся, к тому же такой подход обязывает вызывающую сторону подписатья на событие — раз (что можно и забыть), определить Cаllback два, который в свою очередь будет исполнятся в контексте вызванного потока, что запрещает любые обращения к GUI, а перевод апартмента в STA через Invoke, незамедлительно приводит к дедлоку, если вызывающая сторона держит locк() или join(). В заключении, вызывающая сторона обязанна занать, что функция выполняется в другом потоке( а хотелось-бы прозрачно), event дожен отслеживать аппартмент(что тоже нежелательно).
Все это, ИМХО, еще больше усложняет ситуацию, требуя большей осторожности, и затрудняет сопровождение.
Re[2]: Исключения в потоках.
От:
Аноним
Дата:
28.06.08 16:50
Оценка:
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
Разве ThreadAbortException может делать ретроу черз границы потока?
A>Можно попытаться использовать A>Thread.Abort(Object)
Здравствуйте, <Аноним>, Вы писали:
А>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#).
Ничего не понятно. Что такое границы потока? Как можно использовать коды возврата, если они находятся в стеке, а стек у каждого потока свой? Как может поток обрабатывать исключения из другого потока, если он (первый поток) в этот момент выполняет свой собственный код?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Ваш класс вызывает некую функцию другого класса, каторая в свою очередь, выполняет некий код в другом потоке. В этом коде возбуждается исключение. Как проинформировать Вас о произошедшем, при условии, что принемать решения о далнейших дейсвиях в связи с исключением может толко Ваш класс?
Здравствуйте, Аноним, Вы писали:
А>Ваш класс вызывает некую функцию другого класса, каторая в свою очередь, выполняет некий код в другом потоке. В этом коде возбуждается исключение. Как проинформировать Вас о произошедшем, при условии, что принемать решения о далнейших дейсвиях в связи с исключением может толко Ваш класс?
Значит этот "другой класс", владеющий потоком, должен перевыкинуть исключение.
Здравствуйте, Аноним, Вы писали:
А>Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#).
Стесняюсь спросить, что тогда происходит, если исключение генерирует ремоутинг-сервер, а обрабатывает его ремоутинг-клиент?
В общем случае, это не просто "за пределы потока", это за пределы домена, процесса и машины.
Непонятно.
Здравствуйте, HowardLovekraft, Вы писали:
HL>Стесняюсь спросить, что тогда происходит, если исключение генерирует ремоутинг-сервер, а обрабатывает его ремоутинг-клиент? HL>В общем случае, это не просто "за пределы потока", это за пределы домена, процесса и машины. HL>Непонятно.
Я так подозреваю, что речь все же о GUI-потоке, но вместо того, чтобы упорядочить кашу в голове, товарищь пытается искать проблемы во мне.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, HowardLovekraft, Вы писали: HL>Стесняюсь спросить, что тогда происходит, если исключение генерирует ремоутинг-сервер, а обрабатывает его ремоутинг-клиент? HL>В общем случае, это не просто "за пределы потока", это за пределы домена, процесса и машины. HL>Непонятно.
Я же про ремоутинг ничего не спрашивал.
Два потока в одном процессе, в одном APP домеине. В одном потоке произошло исключение, второй хочет об этом знать. О чем? О том, что в первом потоке произошло исключение. Все.
Про GUI поток, я тоже ничего не говорил. В данном случае неважно если один из этих потоков из STA или оба из МТА.
Здравствуйте, Аноним, Вы писали:
А>Про GUI поток, я тоже ничего не говорил. В данном случае неважно если один из этих потоков из STA или оба из МТА.
А в каком месте (и почему) критично? СТА там или нет? Зачем там часто делать на это упор? И какое это (модель апартаментов) отношение имеет к исключением? Если у тебя там жёсткий интероп с комом — то так и надо было сразу сказать. Если нет — к чему эти укахания?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, <Аноним>, Вы писали:
А>Два потока в одном процессе, в одном APP домеине. В одном потоке произошло исключение, второй хочет об этом знать.
Что значит "хочет знать"?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, Аноним, Вы писали:
А>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку. А>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
Посмотрите в таком направлении:
Delegates
Object.InvokeRequired
Object.Invoke();
Re[2]: Исключения в потоках.
От:
Аноним
Дата:
03.07.08 19:46
Оценка:
RD>Посмотрите в таком направлении: RD>Delegates RD>Object.InvokeRequired RD>Object.Invoke();
private void Evaluate()
{
trow new Exception("");
}
ThreadStart ts = delegate
{
try
{
Evaluate();
}
catch(Exception exc)
{
// поймали, что далше?
}
};
Thread t = new Thread(ts);
t.Start();
t.Join();
И чем здесь помогут Ваши инвоки?
Re: Исключения в потоках.
От:
Аноним
Дата:
13.07.09 07:34
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку. А>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
В потоке можно поднимать UnhandledException. Он точно виден вне границ потока. Кидайте его в потоке и ловите снаружи. А там уже обрабатывайте как Вам угодно.
Здравствуйте, Аноним, Вы писали:
А>Добрый день! Исключения возникшие в потоках нельзя перебросить за пределы потока, они должны обрабатываться в самом потоке(С#). Однако, иногда требуется оповестить внешний код о возникшем ислючении, поэтму я прибегаю к механизму кодов возврата, тем самым создается болшая неразбериха в коде — часть функций выбрасывает исключения , а часть возвращает ошибку. А>Хотелось бы узнать как придать единую структуру, с точки зрения оформления кода, и какие механизмы для етого используются?
А почему бы вам не использовать тот факт что при вызове EndInvoke у асинхронного делегата проталкиваются возникшие исключения
using System;
using System.Threading;
class Program
{
private static void Evaluate()
{
throw new Exception("Oops!!!");
}
static void Main(string[] args)
{
Action action = Evaluate;
var asyncResult = action.BeginInvoke(null, null);
// ждем пока завершится выполнение делегата
// вместо этого можно сделать что-нибудь полезное
asyncResult.AsyncWaitHandle.WaitOne();
try
{
action.EndInvoke(asyncResult);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}