Re: Сдох поток
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.09.23 12:44
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Есть служба в ней работает порядка 20 потоков порожденных new Thread.

Интерересно посмотреть на async с TimeOut
https://stackoverflow.com/questions/71794095/how-to-set-timeout-for-a-task-and-then-abort-it
и солнце б утром не вставало, когда бы не было меня
Re[9]: Сдох поток
От: m2user  
Дата: 21.09.23 13:00
Оценка:
D>Полагаю, что вы можете убедиться в этом с помощью несложного практического эксперимента.

Application: WindowsService1.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Web.Query.Dynamic.ParseException
   at WindowsService1.Service1.Run()
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart()


  код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace WindowsService1 {
    public partial class Service1 : ServiceBase {
        public Service1() {
            InitializeComponent();
        }

        protected override void OnStart(string[] args) {
            new Thread(Run).Start();
        }

        protected override void OnStop() {
        }

        void Run() {
            throw new System.Web.Query.Dynamic.ParseException("", 0);
        }
    }
}
Re[8]: Сдох поток
От: 4058  
Дата: 21.09.23 15:56
Оценка:
Здравствуйте, m2user, Вы писали:

M>Но что касается Windows Service, то от обычного консольного приложения он по сути отличается только обработкой RPC запросов от Service Control Manager и регистрацией в реестре.

M>И от неперехваченных исключений падает точно также, как любое консольное приложение.

Да, действительно это так. Занятно, что в FW 1.0/1.1 исключение выброшенное не из главного потока не приводило к завершению процесса.

In the .NET Framework versions 1.0 and 1.1, an unhandled exception that occurs in a thread other than the main application thread is caught by the runtime and therefore does not cause the application to terminate. Thus, it is possible for the UnhandledException event to be raised without the application terminating. Starting with the .NET Framework version 2.0, this backstop for unhandled exceptions in child threads was removed, because the cumulative effect of such silent failures included performance degradation, corrupted data, and lockups, all of which were difficult to debug.

https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?view=net-7.0
Re: Сдох поток
От: Qt-Coder  
Дата: 25.09.23 09:15
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Есть служба в ней работает порядка 20 потоков порожденных new Thread.


Похоже причина в этом
GC.Collect(2, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
Re[2]: Сдох поток
От: m2user  
Дата: 25.09.23 10:25
Оценка:
QC>Похоже причина в этом
QC> GC.Collect(2, GCCollectionMode.Forced);
QC> GC.WaitForPendingFinalizers();

Ну да, WaitForPendingFinalizers может висеть неопределенное время в зависимости от того, что застряло в очереди на финализацию.
Если ты повторил проблему и снял дамп, то через WinDbg можно посмотреть, что висит в finalizer queue.

Вообще в норме не следует вызывать GC.Collect и GC.WaitForPendingFinalizers вручную. Присутствие их в коде уже повод насторожиться.
Re[3]: Сдох поток
От: Qt-Coder  
Дата: 25.09.23 10:45
Оценка:
Здравствуйте, m2user, Вы писали:

QC>>Похоже причина в этом

QC>> GC.Collect(2, GCCollectionMode.Forced);
QC>> GC.WaitForPendingFinalizers();

M>Ну да, WaitForPendingFinalizers может висеть неопределенное время в зависимости от того, что застряло в очереди на финализацию.

M>Если ты повторил проблему и снял дамп, то через WinDbg можно посмотреть, что висит в finalizer queue.

M>Вообще в норме не следует вызывать GC.Collect и GC.WaitForPendingFinalizers вручную. Присутствие их в коде уже повод насторожиться.


Нет, не снял, просто больше не вижу что могло зависнуть.
Re[4]: Сдох поток
От: m2user  
Дата: 25.09.23 10:58
Оценка: 4 (1)
QC>Нет, не снял, просто больше не вижу что могло зависнуть.

Если предполагаешь, что именно в этом дело, то можно просто и без воспроизведения снять дамп и посмотреть, сколько объектов в finalizer queue. В идеале их должно быть относительно мало (объекты у которых ты не имеешь возможности явно вызвать Dispose — например Thread и т.п.).
Ну и добавить трассировку времени выполнения GC.Collect и GC.WaitForPendingFinalizers.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.