Выйдите из консольного приложения Windows, чтобы очистить ресурсы

1

У меня есть консольное приложение, в котором у меня есть подключение к третьей стороне службы Windows на удаленном сервере с помощью tcp/ip.

Иерархия вызова нравится:

static class Program
{
    [MTAThread]
    static void Main()
    {
        MyApplication.Start();

Метод Start

public static void Start()
{
    lock (SyncVar)
    {
        ThreadStart ts = new ThreadStart(MainCode);
        MainCodeThread = new Thread(ts);
        MainCodeThread.IsBackground = false;
        MainCodeThread.Start();

Деталь основного потока:

private static void MainCode()
{
    try
    {
         // connect to the remote server, against a windows service 
         TelephonyServer tServer = new TelephonyServer(sIpaddress, "username", "password");
         while (true)
         {
            Task consumer = Task.Run(() =>
             {
                   if (data != "")
                   {
                        ProcessEachChannel(data);
            });

            Task producer = Task.Run(() =>
            {
                // blah blah
            });

В методе ProcessEachChannel мы имеем

    public bool ProcessEachChannel(string workItem)
    {
        ChannelResource cr = tServer.GetChannel();
        // blah blah
    }

Теперь приложение работает хорошо. Однако, если я нажму красным краем выхода приложения или нажмите кнопку "Отключить отладку" в Visual Studio, ресурсы ChannelResource cr не будут уничтожены вообще. Я нашел этот факт на панели управления службами удаленного сервера.

Я пробовал код

System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); process.Exited += new EventHandler(OnExited);

Это не полезно. Я слышал некоторые трюки, чтобы управлять потоком, передавая параметры в основной поток, а затем устанавливал что-то true или false т.д., Но просто не знал.

  • 0
    Приложение .NET очищается при разрыве домена приложения, т. Е. При выходе из консольного приложения. Либо TelephonyServer.GetChannel что-то пропускает, либо приборная панель управления службами просто еще не обнаружила, что консольное приложение больше не подключено. Мы не можем проанализировать эту проблему на основании предоставленной информации.
  • 1
    Вы смотрели на это: stackoverflow.com/a/1119869/2638872 ? Вы можете добавить (и обязательно удалить) обработчик для события processExit в ProcessEachChannel с помощью лямбды, которая правильно удаляет объект.
Показать ещё 1 комментарий
Теги:
multithreading

2 ответа

0
Лучший ответ

Если вы убьете этот процесс, а не закрываете его изящно (и это то, что вы делаете, когда закрываете окно консоли или нажимаете stop buttpn в отладчике), нет никаких шансов для запуска любого кода очистки. вы должны реализовать некоторый обработчик выхода, возможно, перехватывая ctrl-c press, а затем возвращайтесь из своих потоков, чтобы все объекты могли очистить себя.

  • 0
    Сложность в том, что я хочу нажать кнопку остановки в отладчике напрямую, а не ctrl-c. Можем ли мы использовать дочернюю нить для выполнения моей цели?
  • 0
    Нет , если вы нажмете стоп, не код вашей программы не может работать больше. это функция кнопки остановки.
Показать ещё 1 комментарий
1

Программа не будет работать, пока все запущенные потоки не будут остановлены.

Замените while (true) в коде потока while (!stopThread.WaitOne(10, false)) где stopThread - это WaitHandle например ManualResetEvent.

Затем, когда приложение выключится, Set событие и дождитесь завершения потока.

Также обратите внимание, что некоторые сторонние фреймворки зависят от того, что Dispose на их объекте, потому что им нужно управлять временем жизни некоторых отдельных потоков, которые они породили. Fe прочитал VoiceElements document и посмотрел, как они вызывают Disconnect и Dispose на ChannelResource которые у них есть из GetChannel(). Пожалуйста, обратитесь к поставщику, когда и где вам нужно самостоятельно выпустить используемые ресурсы.

  • 0
    На самом деле у меня есть код while (true) { ThreadEvent.WaitOne(waitingTime, false); Я просто опущен в вопросе.
  • 0
    Итак, вам все еще нужно добавить WaitHandle, чтобы вы могли выйти из потока. И так как у вас есть 2 WaitHandles than, вам понадобится метод WaitHanle.WaitAny и дождитесь, пока не будет установлено одно из событий, затем действуйте соответствующим образом.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню