none
Насколько корректно при попытке подсчета элементов в графе искользовать следующий алгоритм,это нужно для выставления параметра maxItemsInObjectGraph wcf сервиса

    Вопрос

  •   public static void Loop(object faSrc, ref int faCount)
            {
                gizn[faSrc] = faSrc;
                Type type = faSrc.GetType();
                PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo p in props)
                {
                    faCount++;
                    IList<object> a = new List<object>();
                    object result = p.GetValue(faSrc, BindingFlags.GetProperty, null, null, CultureInfo.CurrentCulture);
                    if (typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && result != null)
                    {
                        Type t1 = result.GetType();
                        PropertyInfo count = t1.GetProperty("Count");
                        if (count != null)
                        {
                            int length = (int)count.GetValue(result, null);
                            for (int i = 0; i < length; i++)
                            {
                                object item = t1.GetProperty("Item").GetValue(result, BindingFlags.InvokeMethod, null, new object[] { i }, CultureInfo.CurrentCulture);
                                faCount++;
                                if (!gizn.ContainsKey(item)
    
                                    && item is object)
                                    Loop(item, ref faCount);
                            }
                        }
                    }
                    else
                        if (result != null)
                    {
                        if (!gizn.ContainsKey(result) && result is object)
                            Loop(result, ref faCount);
                    }
                }
            }

    Количество объектов считается в переменной faCount
    gizn- статический словарик Dictionary<object,object>

    • Изменено WcfQuestion 9 апреля 2018 г. 1:09
    9 апреля 2018 г. 1:07

Ответы

  • Такой эффект возникает если перепутаны местами значения которые возвращает Check(). Тогда окно "ползет" в сторону обратную требуемой.

    Для правильной работы надо чтоб при прохождении проверки менялся max, а при ошибке - min.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    22 апреля 2018 г. 16:17
    Модератор

Все ответы

  • видимо спецов по  wcf здесь нет
    12 апреля 2018 г. 10:12
  • Спецы скорее всего просто приникидывают это число в уме.

    В любом случае вместо угадывания как именно DataContractSerializer считает число объектов я бы просто пропустил бы объект через сериалайзер разными значениями указанного параметера. Фактическое число объектов может быть напечатано в исключении, подсмотретно отладчиком или же оперделено, например, методом половинного деления.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    12 апреля 2018 г. 18:32
    Модератор
  • Метод половинного деления применим только для непрерывных функций, а у меня функция принимающая дискретные значения (true - работает, false-ошибка), а чем мой способ плох, может быть чуток лишнего считает не делая разницы между структурными и объектными свойствами. И значение полученное по самому крупному объекту базы позволяет его получить как результат работы сервиса
    • Изменено WcfQuestion 16 апреля 2018 г. 1:42
    15 апреля 2018 г. 21:52
  • Я вам приведу пример как использовать метод половинного деления в таких случаях. Это скрипт который определяет размер MTU исходя из того проходит ли пинг или нет. 

    @echo off
    
    if "%1" == "" (
    echo Usage: %0 host
    echo.
    echo This script will attempt to discover MTU on a path to particular host.
    echo.
    echo Example: %0 ya.ru
    goto exit
    )
    
    ping -n 1 %1 >nul
    
    if "%ERRORLEVEL%" == "1" (
    echo No responce from host '%1', unable to discover MTU. Try another host.
    goto exit
    )
    
    set MTU_MAX=1500
    set MTU_MIN=68
    set HEADER_SIZE=28
    
    :next
    
    set /a MTU=(MTU_MIN + MTU_MAX) / 2
    
    if "%MTU%" == "%MTU_MIN%" goto show
    if "%MTU%" == "%MTU_MAX%" goto show
    
    echo Trying payload: %MTU%
    
    ping -n 1 -l %MTU% -f %1 >nul
    
    goto e_%ERRORLEVEL%
    
    :e_0
    echo Payload %MTU% - Works
    set MTU_MIN=%MTU%
    goto next
    
    :e_1
    echo Payload %MTU% - Fail
    set MTU_MAX=%MTU%
    goto next
    
    :show
    
    set /a MTU=%MTU%+%HEADER_SIZE%
    
    echo MTU on the path to '%1' is: %MTU%
    
    :exit
    

    Я не знаю плох ваш способ или нет. Как я сказал для оценки размер можно легко прикинуть в уме, а потом увеличить его раз в 10 для надежности.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    15 апреля 2018 г. 22:31
    Модератор
  • Выдалась свободная минутка.Предложенный вами алгоритм некорректен. Перевел его на C#

      long min = 1;
                long max = Int32.MaxValue;
                long err =(long)( (max + min)/2);
                string current = "maxItemsInObjectGraph=\"" + max.ToString() + "\"";
             while (!(err == max || err == min)) {
                    if (Check(err, ref current))
                    {
                        min = err;
                    }
                    else max = err;
                     err = (long)((max + min) / 2);
                                }

    итого получилось в качестве ответа начальное значение max, может конечно я переврал ваш алгоритм, не совсем знаю язык написания скриптов для cmd. Оригинальный алгоритм метода дитохомии позволяет сократить оптимальное значение до миллиона, что примерно идентично тому значению что я посчитал методом Loop, но с какой-то итерации метод перестает сходиться и начинает топтаться на месте:

       long min = 1;
                long max = Int32.MaxValue;
                long err =(long)( (max + min)/2);
     while (err > 1000)
                {
    
                    int c = (max - min) / 2;
    
                bool result1 = Check(min,ref current);
                    bool result2 = Check(c,ref current);
                    if ((result1 ^ result2))
                    {
                        max = c;
                    }
                    else {
                        bool result3 = Check(max, ref current);
                        if ((result2 ^ result3))
                            min = c;
                        else
                            break;
                    }
    
                    err = max - min;
                }

    22 апреля 2018 г. 8:33
  • Такой эффект возникает если перепутаны местами значения которые возвращает Check(). Тогда окно "ползет" в сторону обратную требуемой.

    Для правильной работы надо чтоб при прохождении проверки менялся max, а при ошибке - min.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    22 апреля 2018 г. 16:17
    Модератор