очень долгое время между вызовом диспетчера и выполнением - PullRequest
3 голосов
/ 30 декабря 2010

Заранее извиняюсь, если это глупый вопрос.Я по профессии программист на C, и C # для меня относительно новый.

У меня есть приложение, которое в основном сводится к следующему: один поток, который опрашивает внешний интерфейс (profibus, если кому-то это интересно), когда входные данные изменяются, возникает событие и обрабатываются новые данные.Поскольку данные, которые мне нужно обновить, используют привязку данных, я вызываю диспетчер.Эта настройка работает должным образом миллионы раз, но иногда для выполнения кода в делегате требуется до 6 секунд.Поскольку других тем нет, я не вижу причин для этого.Я использую следующий обработчик событий.Контейнер - это ссылка на TabItem, к которому привязан класс.

public void newSlave_InputChanged(object sender, InputChangedEventArgs e)
    {
        DateTime beforeDisp = DateTime.Now;
        Container.Dispatcher.Invoke(DispatcherPriority.Send, (Action)delegate()
        {
            DateTime afterDisp = DateTime.Now;
            if (afterDisp.Subtract(beforeDisp).TotalSeconds > 1)
            {
                /* Breakpoint here to detect the problem */               
            }
            /* Do the work I need to do */           

        }
    );
    }

Поток, опрашивающий внешний интерфейс, в основном выглядит примерно так:

void monitorSlaves()
    {
        while (true)
        {
            if (cardOnline)
            {
                foreach (slave slv in slaves)
                {
                    /* get the data */
                        if (dataChanged)
                        {
                            /* raise event */
                        }
                    }
                }
                Console.WriteLine(string.Format("{0}: Monitor slaves", DateTime.Now));
            }
            Thread.Sleep(200);
        }
    }

Я добавил печать впосмотрите, работает ли этот поток, пока диспетчер "зависает".Как оказалось, это не так.Я понятия не имею, что делает программа в считанные секунды между вызовом и выполнением, поскольку, насколько мне известно, других потоков нет.К сожалению, у меня нет окончательной лицензии на Visual Studio 2010, поэтому я не могу использовать intellitrace для отслеживания того, что было запущено.

Любая информация очень ценится.

Ответы [ 3 ]

0 голосов
/ 30 декабря 2010

Вы уверены, что видите входные данные, когда думаете, что это так?

Одной из возможных проблем является то, что DLL-карта интерфейсной карты не сообщает о входных данных своевременно.

Другая возможная проблема заключается в том, что поток пользовательского интерфейса слишком занят, чтобы запустить ваш делегат. Тем не менее, 6 секунд - это long время, которое не отвечает.

Вы можете добавить простую трассировку, чтобы определить причину. Просто позвоните Trace.TraceInformation для записи простых строк в режиме Release. Затем загрузите DebugView, который может отображать эти сообщения трассировки. Вы также можете настроить DebugView для отметки времени и сохранения их в файл.

P.S. По совпадению я разработчик .NET, который сейчас работает над встроенными прошивками. :)

0 голосов
/ 30 декабря 2010

Бьюсь об заклад, потому что сборщик мусора собирает кучу маленьких объектов, которые вы создали.запустите perfmon и посмотрите всю коллекцию.

0 голосов
/ 30 декабря 2010

использование thread.sleep - это, как правило, плохая практика, вы можете заморозить весь поток пользовательского интерфейса, чтобы Dispatcher не вызывался должным образом.Я рекомендую использовать DispatcherTimer вместо

...