当初学者问类似于:如何在C#中从另一个线程更新GUI?时,答案很简单:
if (foo.InvokeRequired)
{
foo.BeginInvoke(...)
} else {
...
}
但是真的适合使用吗?在非GUI线程执行
foo.InvokeRequired
后,foo
的状态可能会发生改变。例如,如果我们在调用 foo.BeginInvoke
之前关闭表单,调用 foo.BeginInvoke
将导致 InvalidOperationException
:直到窗口句柄被创建之前,不能在控件上调用 Invoke 或 BeginInvoke。 如果我们在调用 InvokeRequired
之前关闭表单,这种情况就不会发生,因为即使从非GUI线程调用时,它也将是 false
。相比之下,我认为使用
WindowsFormsSynchronizationContext
更容易 - 使用 Post
发布回调仅会在线程仍然存在时发生,并且使用 Send
进行同步调用,如果线程不再存在,则会抛出 InvalidAsynchronousStateException
。难道使用
WindowsFormsSynchronizationContext
不是更简单吗?我漏看了什么吗?如果 InvokeRequired-BeginInvoke 模式实际上不是线程安全的,为什么要使用它?你认为哪个更好?
Control.IsDisposed
的作用(https://msdn.microsoft.com/en-us/library/system.windows.forms.control.isdisposed(v=vs.110).aspx)。 - Ohad SchneiderApplication.ThreadContext.FromCurrent().MarshalingControl
或访问WindowsFormsSynchronizationContext
成员controlToSendTo
,但这有点繁琐。 - Julien RoncagliaControl.isDisposed
可以工作。我看不到我5年前所说的问题XD 我会编辑它。 - Julien Roncaglia