Обработчик событий истекшего таймера, не может запустить определенный код внутри него - PullRequest
1 голос
/ 10 марта 2011

У меня тут какая-то странность.

У меня есть такая пустота

private void Filter()
{
    MyDataView.RowFilter = string.Format("Name LIKE '%{0}%'", tb_Filter.Text);
}

Затем у меня есть обработчик прошедшего таймера, и его метод выглядит так

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    Filter();
}

Я положил timer.AutoReset в false и поместил timer.Start () внутри обработчика событий для кнопки.Я нажимаю кнопку, ничего не происходит.Он просто на некоторое время зависает, а затем выдает это:

An unhandled exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll

Additional information: Object reference not set to an instance of an object.

Если я запускаю метод Filter () из любого другого обработчика событий (button_click, textoted, что угодно), он работает нормально,Если я помещу любой другой код в обработчик события timer_Elapsed, перед вызовом Filter () он запустится.Например:

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("this works");
    }

напечатает «это работает» на консоли, когда таймер истечет.

Я сбит с толку.Что я здесь не так делаю?
Почему мой метод Filter () запускается для любого события, кроме timer_elapsed?

РЕДАКТИРОВАТЬ: Получено более подробное исключение:

Первое случайное исключение типа «System.InvalidOperationException» произошло в WindowsBase.dll

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

Ответы [ 3 ]

2 голосов
/ 10 марта 2011

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

Вместо этого используйте обычный таймер Winforms.

0 голосов
/ 05 апреля 2013

Кажется, что ваш обработчик timer_Elapsed запускается в потоке, отличном от UI.Это означает, что вы можете выполнять оттуда независимые от потоков действия (например, печать в консоль), но у вас ничего не получится, если вы попытаетесь получить доступ к объектам пользовательского интерфейса.

Вы можете прочитать об этих проблемах здесь: http://msdn.microsoft.com/en-us/magazine/cc163328.aspx В качестве быстрого решения вы можете заменить

MyDataView.RowFilter = string.Format("Name LIKE '%{0}%'", tb_Filter.Text);

чем-то вроде

Dispatcher.Invoke(new Action(() => { MyDataView.RowFilter = string.Format("Name LIKE '%{0}%'", tb_Filter.Text); }));
0 голосов
/ 10 марта 2011

Возможно ли, что выдается исключение?Я обычно включаю опцию Отладка -> Исключения -> Общеязыковые исключения во время выполнения и пытаюсь снова.

...