Я хочу передать исключение из текущего потока (этот поток не является основным потоком) в основной поток. Почему? Поскольку я проверяю свою жесткую блокировку в другом потоке (этот поток использует таймер для проверки), а когда HardLock
недоступен или недействителен, я создаю исключение, которое определяется мной, а затем выкидывает это исключение.
Чтобы исключение не срабатывало. ; (Отправка исключения из потока в основной поток?
ответ
Ваш лучший выбор - заменить Thread
на Task
(новый в .NET 4.0). Класс Task
обрабатывает правильное маршалинг исключения, независимо от того, какой поток проверяет результат задачи.
Если использование .NET 4.0 невозможно, то CoreEx.dll из Rx extensions включает в себя метод расширения Exception.PrepareForRethrow
, который сохраняет стек вызовов для исключений. Вы можете использовать это в сочетании с предложением MaLio о SynchronizationContext
для исключения исключения из другого потока.
не зная ничего другого, кажется, что ваш замок сломан, если вам нужен поток, чтобы убедиться, что замки не проводятся слишком долго или являются недействительными
Если вам действительно нужно бросить исключения. ваш основной поток, настройте очередь сообщений из всех ваших «рабочих потоков» на ваш «главный поток» и оберните все рабочие потоки в обработчик исключений, который делает ничего, кроме добавления исключений в очередь и затем убивает этот поток. главный поток может опросить очередь, чтобы обнаружить исключения и перезапустить потоки, которые умерли после исправления состояния ошибки.
Передайте ссылку на контекст выполнения основной формы на t он нить (через делегата или поле). Затем вызовите метод (отправить или отправить) через этот контекст синхронизации из потока, который выдает исключение. Контекст выполнения гарантирует, что он обрабатывается нитью ui.
Возможно, вам будет легче сохранить обработку исключений в потоке и передать сообщение об исключении и трассировку стека, возвращая MyException.ToString()
в обратном вызове. Когда я получаю исключения из другого потока, все, что я ищу, находится в этой строке.
Только мои 2 цента.
Я думаю, вы можете использовать Invoke, BeginInvoke в основной форме, если вы используете Windows Forms для отправки исключения из блока try/catch. Или вы можете создать обработчик/делегат события в основном потоке и отправить исключения через него в основной поток, чтобы метод в основном потоке мог его обработать. Честно говоря, не пробовали эти решения, но это мои первые идеи.
PS. Возможно, создание WorkerQueue в основном потоке также является опцией. Он будет работать как backgroundWorker, и когда он получит новое отправленное исключение, он обработает его соответственно ... Я могу дать вам небольшие примеры, если вы заинтересованы.
Edit:
public class JobQueue
{
private Queue<Exception> pendingJobs = new Queue<Exception>();
private Exception defaultJob = null;
bool run = true;
public void AddJob(Exception job)
{
pendingJobs.Enqueue(job);
}
public JobQueue()
{
defaultJob=null;
}
public void StopJobQueue()
{
run = false;
}
public void Run()
{
while (run)
{
Exception job = (pendingJobs.Count > 0) ? pendingJobs.Dequeue() : defaultJob;
if (job!= null)
{
////what to do with current Exception
}
Thread.Sleep(20); //I know this is bad...
}
pendingJobs.Clear();
}
}
}
Чтобы использовать его: В вашей основной класс резьбы:
private JobQueue m_jobQueue;
В Initialize() или там, где ваши главные старты резьбы:
Backgroundworker bw = new Backgroundworker();
bw.DoWork+= jobQueue.Run;
bw.StartAsync();
//m_jobQueue = new JobQueue();
// new Thread(new ThreadStart(jobQueue.Run)).Start();
И для отправки исключения:
m_jobQueue.AddJob(StackOverflowException);
Остановка по:
m_jobQueue.StopJobQueue();
Вы никогда не назначаете 'defaultJob' (или я что-то не хватает?), Для чего он нужен? Простой заменой 'Thread.Sleep' является использование AutoResetEvent (даже работает на Windows Mobile). Создайте новый 'AutoResetEvent', сделайте' while (pendingJobs.Count> 0) {job = pendingJobs.Dequeue(); } ', в случае, если новое задание попадает в очередь в процессе выделения, внутри вашего другого и кладет' resetEvent.WaitOne' вместо Thread.Sleep. В 'Enqueue' вы можете сделать' resetEvent.Set() ', чтобы разбудить его в' Run() '. – Patrick
Привет, Патрик! Ты прав. Я просто в основном скопировал его из моего проекта, удалив большую часть кода для простоты. Виноват. Но, по крайней мере, в качестве примера я думаю, что это будет сделано. Спасибо, что указали эти моменты. – nomail
Вы можете использовать исключение в качестве параметра в случае.
И обрабатывайте его после отправки исключения в другой поток.
Пример кода.
public delegate void SendToMainDel(string threadName,Exception ex);
public event SendToMainDel SendToMainEv;
public void MySecondThread()
{
try
{
....
}catch(Exception ex)
{
if(SendToMainEv!=null)
SendToMainEv("MySecondThread",ex);
}
}
...
SendToMainEv += ReceiveOtherThreadExceptions;
...
public void ReceiveOtherThreadExceptions(string threadName,Exception ex)
{
if(InvokeRequired)
{
BeginInvoke(new SendToMainDel(ReceiveOtherThreadExceptions), threadName, ex);
return;
}
//there you can handle the exception
//throw ex;
}
- 1. Передача исключения или сообщение из потока/задачи в основной поток
- 2. Отправка сигнала от основной функции в поток?
- 3. Как заморозить основной поток из рабочего потока
- 4. Java: периодическая отправка данных из потока в основной класс
- 5. Переход от фонового потока в основной поток
- 6. Отправка сообщений из потока в поток без ожидания
- 7. Очистка дочерних потока, когда основной поток завершается
- 8. Можно ли вызвать основной поток из рабочего потока в Java?
- 9. Как отправить сигнал/данные из рабочего потока в основной поток?
- 10. Получение информации обратно в основной поток из вызываемого потока?
- 11. Выполнить метод из вторичного потока на основной поток в C#?
- 12. Передача данных из фонового потока в основной поток
- 13. Как уведомить ожидающий основной поток из пользовательского потока в java?
- 14. Блок основной поток до рабочего потока завершается
- 15. NSOperationQueue и отправка делегатом основной поток
- 16. MFC: отправка msg из рабочего потока в главный поток, чтобы остановить рабочий поток
- 17. Java Swing: Как просыпаться основной поток из потока событий?
- 18. ArcGIS Explorer: вызывать основной поток из вторичного потока
- 19. Почему исключения не останавливаются поток потока Akka
- 20. Отправка сообщений в поток?
- 21. Как мне скопировать значения изнутри потока обратно в основной поток?
- 22. можно ли изменить операцию фонового потока в основной поток?
- 23. UISegmentedControl setTitle: forSegmentAtIndex :, явная отправка в основной поток?
- 24. поток потока потока Linux
- 25. Получить основной поток из вторичной нити
- 26. Получение потока исключения OutOfMemory
- 27. Закрытие потока после исключения
- 28. C++ новый поток спит основной поток
- 29. Вызов из неправильного исключения потока
- 30. Прямой поток сжатия (из потока)
я могу использовать 'публичный статический method' в Program.cs и вызвать его из другого потока (Потому что это статический класс), и прекратить применение с' application.exit', но это хорошо только для завершения приложения ' НЕ делайте никаких других действий! – Rev