none
Как убить поток и как убить WMI? RRS feed

  • Общие обсуждения

  • Делаю следующее:

    Dim LockObject As New Object
            For Each server As String In ServerList
                Dim S As New Сервер(server)
                Dim T As New Thread(AddressOf S.Проверить)
                T.IsBackground = True
                T.Name = server
                T.Start()
                ThreadList.Add(T)  ' добавить запущенные потоки в список
            Next
            Debug.WriteLine("Всего запущено потоков - " & ThreadList.Count)
            For n = 0 To 5 Step 1
                PrintStatistics()
                System.Threading.Thread.Sleep(2000)
            Next
            For Each thr As Thread In ThreadList
                If thr.IsAlive Then
                    Debug.WriteLine("ЖИВ поток " & thr.Name & ", ID=" & thr.ManagedThreadId)
                End If
            Next
    
        Sub PrintStatistics()
            Dim n As Integer = 0
            For Each thr As Thread In ThreadList
                If thr.IsAlive Then
                    n += 1
                End If
            Next
            Debug.WriteLine("Живых потоков - " & n)
        End Sub

    И в окне отладчика получаю:

    Всего запущено потоков - 295
    Живых потоков - 21
    Живых потоков - 4
    Живых потоков - 4
    Живых потоков - 4
    Живых потоков - 4
    Живых потоков - 4
    ЖИВ поток F04-N07, ID=38
    ЖИВ поток F04-N16, ID=39
    ЖИВ поток F04-N05, ID=40
    ЖИВ поток F04-N03, ID=90

    Как видно, несколько потоков из запущенных - не заканчиваются. Опыты типа Поток.Abort или .Interrupt результатов не дают. Соответственно при отладке я получаю исключение: "An attempt has been made to free an RCW that is in use.  The RCW is in use on the active thread or another thread.  Attempting to free an in-use RCW can cause corruption or data loss."

    Отсюда вопросы.

    1. Каким образом можно прибить эти потоки?

    2. Эти потоки висят потому, что назначение каждого из них - обращение по WMI к отдельному серверу с неким запросом. Часть серверов (не всегда одни и те же) не могут корректно обработать запрос и вешают соединение. Причем пробовал делать подобный запрос и через VBS, и через сторонний софт (WMIExplorer, к примеру). Результат один - все виснет. 

    Опыты с таймаутом типа следующего тоже не помогают:

    Dim connStr As String = "\\" & server & "\root\CIMV2" Dim scope As ManagementScope = New ManagementScope(connStr) Dim options As EnumerationOptions = New EnumerationOptions options.Timeout = New TimeSpan(0, 0, 10) scope.Options.Timeout = New TimeSpan(0, 0, 10)


    В общем - "растерялася я..."  :)

    24 июня 2014 г. 18:32

Все ответы

  • Прервать управляемый поток в момент выполнения им неуправляемого кода нельзя. Видимо, "копать" нужно в направлении реализации прерываемого wmi-запроса. Как Вы его выполняете, можете показать?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    25 июня 2014 г. 6:59
  • http://msdn.microsoft.com/ru-ru/library/dd997396(v=vs.110).aspx

    Все должно быть просто, очень просто, настолько просто, на сколько это возможно!

    27 июня 2014 г. 9:51
  • http://msdn.microsoft.com/ru-ru/library/dd997396(v=vs.110).aspx


    Посмотрел, но понял немного. Я с таким до сих пор не сталкивался...

    28 июня 2014 г. 19:05
  • Прервать управляемый поток в момент выполнения им неуправляемого кода нельзя. Видимо, "копать" нужно в направлении реализации прерываемого wmi-запроса. Как Вы его выполняете, можете показать?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Запрос выглядит так:

            Dim connStr As String = "\\" & ServerName & "\root\CIMV2"
            Dim scope As ManagementScope = New ManagementScope(connStr)
            Dim options As EnumerationOptions = New EnumerationOptions
            options.Timeout = New TimeSpan(0, 0, 10)
            scope.Options.Timeout = New TimeSpan(0, 0, 10)
            scope.Connect()
    
            Dim query As ObjectQuery
            Dim searcher As ManagementObjectSearcher
            Dim queryCollection As ManagementObjectCollection
            Dim m As ManagementObject
            query = New ObjectQuery("SELECT * FROM Win32_Printer WHERE caption LIKE '%Client%'")
            searcher = New ManagementObjectSearcher(scope, query)
            queryCollection = searcher.Get()
            Dim PrintersCount As Integer = queryCollection.Count

    28 июня 2014 г. 19:16
  • Во-первых, объект EnumerationOptions у Вас не используется. Видимо его нужно отдать конструктору ManagementObjectSearcher.

    Во-вторых, можете в отладчике определить, на каком именно вызове висит поток?


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    29 июня 2014 г. 7:20
  • Если честно - я не знаю, как это сделать (на каком вызове висит поток)
    2 июля 2014 г. 11:52
  • Запускаете программу в отладчике (F5), после определения факта наличия незавершенных потоков делаем паузу в отладке, открываем окна 'Потоки' и 'Стек вызовов', выбираем поток и по стеку вызовов определяем, где он висит.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июля 2014 г. 12:12
  • Попробовал. Висят 4 потока. 

    Картинка вот такая:

    2 июля 2014 г. 12:40
  • Похоже, на перечислении Ваши потоки и висят. Вы опции с таймаутом Searcher-у отдали как я советовал?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июля 2014 г. 13:25
  • Похоже, на перечислении Ваши потоки и висят. Вы опции с таймаутом Searcher-у отдали как я советовал?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Опции отдал - и ПРОСКОЧИЛО! Живых потоков - 0. Выдает исключение в коде "Timed Out". 

    Как мне кажется - проблема решена.

    СПАСИБО ОГРОМНОЕ!!!!

    2 июля 2014 г. 13:38
  • Если проблема решена переведите тему в категорию вопросов и отметьте подходящее сообщение в качестве ответа.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июля 2014 г. 16:33