我有一个显示底层异步对象状态的控件。该对象引发事件,这些事件到达表单,在那里它们基本上排队并最终使用 BeginInvoke 进行调用。
当控件被废弃时就会出现问题。因为事情是异步发生的,这意味着事件回调在处理过程中总是可能排队,所以我有时会收到 InvalidOperationException(在创建窗口句柄之前无法在控件上调用 Invoke 或 BeginInvoke)。
这不是我想要的行为。我希望即使控件已被释放,回调也能执行(即使这会导致回调中出现异常;这对我来说是一个更有用的异常!)。我想处理每个回调中的已处置状态行为(通常如果已处置则跳过,但有时不是[例如,一个控件记录事件(可选到文件),并且我不想丢失日志数据!]。)。
有没有一种方法可以按照我想要的方式工作?我可以自己写一个不易碎的吗?
Try SynchronizationContext.Current
反而。这有Post
and Send
成员其中roughly map to BeginInvoke
and Invoke
on Control
。只要 UI 线程相对于特定控件处于活动状态,这些操作就会继续运行。
方式SynchronizationContext
并非特定于 WinForms,利用它的解决方案可以移植到其他框架,例如 WPF。
例如。
开始调用代码
void OnButtonClicked() {
DoBackgroundOperation(this);
}
void DoBackgroundOperation(ISynchronizedInvoke invoke) {
ThreadPool.QueueUserWorkItem(delegate {
...
delegate.BeginInovke(new MethodInvoker(this.BackgroundOperationComplete), null);
});
}
同步上下文代码
void OnButtonClicked() {
DoBackgroundOperation(SynchronizationContext.Current);
}
void DoBackgroundOperation(SynchronizationContext context) {
ThreadPool.QueueUserWorkItem(delegate {
...
context.Post(delegate { this.BackgroundOperationComplete() }, null);
});
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)