Время отклика командлета [дубликат]

Я думал, что принятый ответ будет правильным, основываясь на том, что я читал в smarthelp для метода Except: «Производит заданное различие двух последовательностей, используя сопоставитель равенства по умолчанию для сравнения значений». Но я обнаружил, что это не очень хороший ответ.

Рассмотрим этот код:

  Словарь & lt; string, List & lt; string & gt; & gt;  oldDict = новый словарь & lt; string, List & lt; string & gt; & gt; () {{"001A", новый список & lt; string & gt;  {"John", "Doe"}}, {"002B", новый List & lt; string & gt;  {«Франк», «Abignale»}}, {"003C", новый List & lt; string & gt;  {«Doe», «Jane»}}};  Словарь & lt; string, List & lt; string & gt; & gt; & gt;  newDict = новый словарь & lt; string, List & lt; string & gt; & gt; () {{"001A", новый список & lt; string & gt;  {"John", "Doe"}}, {"002B", новый List & lt; string & gt;  {«Франк», «Abignale»}}, {"003C", новый List & lt; string & gt;  {«Doe», «Jane»}}};  bool equal = oldDict.Count.Equals (newDict.Count) & amp; & amp; & amp;  ! OldDict.Except (newDict) .Any ();  Console.WriteLine (string.Format ("oldDict {0} newDict", равно? "Равно": "не равно"));  equal = oldDict.SequenceEqual (newDict);  Console.WriteLine (string.Format ("oldDict {0} newDict", равно? "Равно": "не равно"));  Console.WriteLine (string.Format ("[{0}]", string.Join (",", oldDict.Except (newDict) .Select (k = & gt; string.Format ("{0} = [{1}  ] ", k.Key, string.Join (", ", k.Value))))));   

Это приводит к следующему:

  oldDict не соответствует newDict oldDict не равен newDict [001A = [John, Doe], 002B = [Frank  , Abignale], 003C = [Doe, Jane]]  

Как вы можете видеть, оба «oldDict» и «newDict» настроены точно так же. И ни предлагаемое решение, ни призыв к SequenceEqual не работают должным образом. Интересно, является ли это результатом Исключения, используя ленивую загрузку или способ, которым сравнитель устанавливает для Словаря. (Хотя, глядя на структуру и пояснения, предположим, что это должно быть.)

Вот решение, которое я придумал. Обратите внимание, что правило, которое я использовал, выглядит следующим образом: два словаря равны, если оба содержат одинаковые ключи и значения для каждого совпадения ключей. Оба ключа и значения должны быть в одном и том же порядке. И мое решение может быть не самым эффективным, так как оно полагается на итерацию через весь набор ключей.

  private static bool DictionaryEqual (Dictionary & lt; string, List & lt; string & gt; gt; olddict, Dictionary & lt; string, List & lt; string & gt ;, newDict) {// Простая проверка, являются ли значениями одинаковые  ?  if (! oldDict.Count.Equals (newDict.Count)) возвращает false;  // Проверяем ключи, если (! OldDict.Keys.SequenceEqual (newDict.Keys)) возвращает false;  // Проверяем значения для каждого ключа foreach (строковый ключ в oldDict.Keys), если (! OldDict [key] .SequenceEqual (newDict [key])) возвращает false;  return true;  }  

Также посмотрите, как изменится результат, если: порядок клавиш не совпадает. (возвращает false)

  newDict = новый словарь & lt; string, List & lt; string & gt; () {{"001A", новый List & lt; string & gt;  {"John", "Doe"}}, {"003C", новый List & lt; string & gt;  {«Doe», «Jane»}}, {"002B", новый List & lt; string & gt;  {«Фрэнк», «Abignale»}}};   

и совпадения с порядковым номером, но значение не соответствует (возвращает false)

  newDict = новый словарь & lt; string, List & lt; string & gt; & gt; ()  {{"001A", новый список & lt; string & gt;  {"John", "Doe"}}, {"002B", новый List & lt; string & gt;  {«Франк», «Abignale»}}, {"003C", новый List & lt; string & gt;  {"Джейн Доу"}}};   

Если порядок последовательности не имеет значения, функция может быть изменена следующим образом, но, скорее всего, будет производительный удар.

  private static bool DictionaryEqual_NoSort (  Словарь & lt; string, List & lt; string & gt; gt; oldDict, Dictionary & lt; string, List & lt; string & gt; & gt; newDict) {// Простая проверка, совпадают ли подсчеты?  if (! oldDict.Count.Equals (newDict.Count)) возвращает false;  // перебираем все ключи в oldDict и // проверяем, существует ли ключ в newDict foreach (строковый ключ в oldDict.Keys) {if (newDict.Keys.Contains (key)) {// повторять каждое значение для  текущий ключ в oldDict и // проверить, существует ли он для текущего ключа в newDict foreach (строковое значение в olddict [key]), если (! newDict [key] .Contains (value)) возвращает false;  } else {return false;  }} return true;  }  

Проверьте, не использует ли DictionaryEqual_NoSort следующее для newDict (DictionaryEquals_NoSort возвращает true):

  newDict = новый словарь & lt; string, List & lt; string & gt; & gt; & gt; & gt;  ; () {{"001A", новый List & lt; string & gt;  {"John", "Doe"}}, {"003C", новый List & lt; string & gt;  {"Jane", "Doe"}}, {"002B", новый List & lt; string & gt;  {«Фрэнк», «Abignale»}}};   
3
задан Kermit 19 April 2013 в 16:24
поделиться

6 ответов

Единственными двумя решениями, которые я видел для этой проблемы, являются:

  1. Запускать запросы в качестве фоновых заданий и накладывать на них таймер, а затем останавливать / удалять задания, выполняющиеся слишком долго.
  2. Исправьте серверы.
2
ответ дан mjolinor 16 August 2018 в 00:42
поделиться
  • 1
    Благодаря! Я запускаю это уже в задании (с start-job -scriptpath). Должен ли я по-прежнему делать -асбь из начала работы? – Sune 15 March 2012 в 00:01
  • 2
    Я не вижу, чтобы работа вложенности была какой-то помощью. Для работы таймера вам нужно выполнить одно задание на сервер. Это добавит пару секунд накладных расходов для каждого из них, чтобы создать задание, но вы можете запускать сразу несколько заданий. Вам нужно будет создать скрипт, в котором будет выполняться x количество заданий одновременно, по одному для каждого сервера, а затем получение или отмена заданий по мере их завершения или их ET слишком длинный, а затем удаление этого задания и запуск нового со следующего сервера в списке. – mjolinor 15 March 2012 в 00:09
  • 3
    Запрос get-wmiobject - это лишь одна из многих вещей, которые я выполняю в своей работе, но работа зависает, если get-wmiobject не отвечает должным образом. Я попытаюсь сделать get-wmiobject -asjob и подождать, пока работа завершено, чтобы продолжить. Возможно, это не лучшая практика, но я не вижу другого пути. – Sune 15 March 2012 в 00:16

Радует мою функцию Get-WmiCustom здесь http://blogs.msdn.com/b/dmuscett/archive/2009/05/27/get_2d00_wmicustom.aspx полезен.

2
ответ дан Daniele Muscetta 16 August 2018 в 00:42
поделиться

Я модифицировал Get-WmiCustom Daniel Muscetta для поддержки передачи учетных данных.

Я знаю, что этот пост немного стар, надеюсь, это помогает кому-то другому.

# Define modified custom get-wmiobject for timeout with credential from http://blogs.msdn.com/b/dmuscett/archive/2009/05/27/get_2d00_wmicustom.aspx
Function Get-WmiCustom([string]$Class,[string]$ComputerName,[string]$Namespace = "root\cimv2",[int]$Timeout=15, [pscredential]$Credential) 
{ 
    $ConnectionOptions = new-object System.Management.ConnectionOptions
    $EnumerationOptions = new-object System.Management.EnumerationOptions

    if($Credential){
        $ConnectionOptions.Username = $Credential.UserName;
        $ConnectionOptions.SecurePassword = $Credential.Password;
    }


    $timeoutseconds = new-timespan -seconds $timeout 
    $EnumerationOptions.set_timeout($timeoutseconds)

    $assembledpath = "\\$Computername\$Namespace"
    #write-host $assembledpath -foregroundcolor yellow

    $Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions 
    $Scope.Connect()

    $querystring = "SELECT * FROM " + $class 
    #write-host $querystring

    $query = new-object System.Management.ObjectQuery $querystring 
    $searcher = new-object System.Management.ManagementObjectSearcher 
    $searcher.set_options($EnumerationOptions) 
    $searcher.Query = $querystring 
    $searcher.Scope = $Scope

    trap { $_ } $result = $searcher.get()

    return $result 
}
0
ответ дан Erik 16 August 2018 в 00:42
поделиться

Вы можете попробовать функцию get-wmiCustom, размещенную здесь здесь . Было бы неплохо, если бы у get-wmiObject был параметр тайм-аута? Возьмем эту вещь .

2
ответ дан noam 16 August 2018 в 00:42
поделиться

при создании задания с использованием get-wmiobject назначает это задание переменной, то эту переменную можно передать в get-job для статуса или получения-задания для результатов

$ThisJob = start-job -scriptblock {param ($Target) Get-WmiObject -Class Win32_Service -ComputerName $Target -AsJob} -ArgumentList $server
$Timer = [System.Diagnostics.Stopwatch]::StartNew()
While ($ThisJob | Get-Job | where {$_.State -imatch "Running"}){
    If ($Timer.Elapsed.Seconds -ge 5) {
        echo "five seconds has passed, removing"
        $ThisJob | Get-Job | Remove-Job -Force
        } # end if
    echo "still running"
    Start-Sleep -Seconds 3
    } # end while

$Results = $ThisJob | where {$_.State -inotmatch "failed"} | receive-job
$Timer.Stop | out-null
0
ответ дан Ro Yo Mi 16 August 2018 в 00:42
поделиться

В дополнение к тому, что было сказано, а не пуленепробиваемым решением, но сначала рассмотрите pinging ваших серверов (Test-Connection), он может ускорить время выполнения, если у вас нет машин-ответчиков.

1
ответ дан Shay Levy 16 August 2018 в 00:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: