Timer Elapsed 事件处理程序,无法在其中运行特定代码
Posted
技术标签:
【中文标题】Timer Elapsed 事件处理程序,无法在其中运行特定代码【英文标题】:Timer Elapsed event handler, can't run specific code inside it 【发布时间】:2011-07-12 07:11:33 【问题描述】:这里发生了一些奇怪的事情。
我有这样的空虚
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.
如果我从任何其他事件处理程序(button_click、textchanged 等)内部运行 Filter() 方法,它运行良好。 如果我在 timer_Elapsed 事件处理程序中放入任何其他代码,在调用 Filter() 之前,它将运行。例如:
void timer_Elapsed(object sender, ElapsedEventArgs e)
Console.WriteLine("this works");
将在计时器结束时将“this works”打印到控制台。
我很困惑。我在这里做错了什么? 为什么我的 Filter() 方法会在除 timer_elapsed 之外的任何事件上运行?
编辑:有一个更详细的例外:
在 WindowsBase.dll 中发生了“System.InvalidOperationException”类型的第一次机会异常
附加信息:调用线程无法访问此对象,因为不同的>线程拥有它。
【问题讨论】:
线程异常?你有什么没有告诉我们的吗? 嗯,这个计时器的重点是在 textbox.textchanged 事件处理程序上设置一个延迟。我希望能够在用户在文本框中输入时实时过滤这个绑定到数据网格的数据视图,但是它有点慢,所以我打算在用户停止输入后对过滤方法进行一点延迟。我猜计时器在它自己的线程上运行,idk。但我想通了,我改用调度程序计时器,它似乎工作正常。 几乎看不出有什么问题,多一些细节会很棒 如果您使用System.Timers.Timer
,则需要设置SynchronizingObject
,以便在UI 线程上调用Elapsed
事件处理程序。另一种方法是使用System.Windows.Forms.Timer
或等效的 WPF 计时器(我总是忘记它的名称)。
【参考方案1】:
Elapsed 事件处理程序在线程池线程上运行。这是 RowFilter 属性的毒药,分配它会导致控件被更新。这只能在 UI 线程上完成,用户界面组件永远不是线程安全的。
改用常规的 Winforms 计时器。
【讨论】:
【参考方案2】:是否有可能抛出异常?我通常会启用 Debug -> Exceptions -> Common Language Runtime Exceptions 选项,然后再试一次。
【讨论】:
我从中得到了更多细节。我将编辑第一篇文章。【参考方案3】:您的 timer_Elapsed 处理程序似乎是在与 UI 不同的线程中启动的。这意味着您可以从那里执行与线程无关的操作(例如打印到控制台),但如果您尝试访问 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); ));
【讨论】:
以上是关于Timer Elapsed 事件处理程序,无法在其中运行特定代码的主要内容,如果未能解决你的问题,请参考以下文章
使用 StructureMap 在 Timer_Elapsed 中处理 Datacontext 操作
如何在Timer事件处理程序中获取Timer对象列表的列表索引