C# 为什么';BackgroundWorker是否需要在ProgressChanged事件处理程序中调用?
既然C# 为什么';BackgroundWorker是否需要在ProgressChanged事件处理程序中调用?,c#,.net,backgroundworker,C#,.net,Backgroundworker,既然ProgressChanged事件处理程序是从DoWork事件处理程序中的某个位置引发的,那么它们不应该在异步操作线程上调用吗?异步操作线程也运行DoWork,而不是UI线程,因此需要调用或BeginInvoke来操作控件 我的猜测是,ReportProgress方法中发生了一些神奇的事情,但它怎么知道调用ProgressChanged事件处理程序时哪个线程是正确的呢?当调用RunWorkerAsync时,BackgroundWorker在内部创建一个与当前同步上下文关联的新上下文,该上下文
ProgressChanged
事件处理程序是从DoWork
事件处理程序中的某个位置引发的,那么它们不应该在异步操作线程上调用吗?异步操作线程也运行DoWork
,而不是UI线程,因此需要调用或BeginInvoke
来操作控件
我的猜测是,
ReportProgress
方法中发生了一些神奇的事情,但它怎么知道调用ProgressChanged
事件处理程序时哪个线程是正确的呢?当调用RunWorkerAsync
时,BackgroundWorker
在内部创建一个与当前同步上下文关联的新上下文,该上下文通过static属性检索
此同步上下文将是派生自的类的实例。具体类型取决于应用程序使用的同步模型提供程序。如果您运行的是Windows窗体,则会是;关于WPF;是的
当您随后在后台线程上调用ReportProgress
时,BackgroundWorker
将在内部调用前面提到的SynchronizationContext
实例,从而将操作异步分派到关联的线程
在Windows窗体中,这是作为调用实现的;在WPF上,它变成了一个调用。或者您可以使用ilspy在封面下查看。正如rene的评论中提到的,我只是读了一些关于
WindowsFormsSynchronizationContext
。正确的做法是:AsyncOperationManager.SynchronizationContext
生成“WindowsFormsSynchronizationContext
,默认情况下,AutoInstall
设置为true
,因此知道。。到底是什么?运行消息队列的线程,还是创建第一个控件的线程?或者它只是保存“主窗体”以便以后调用BeginInvoke
?顺便说一句,我注意到当在另一个线程上创建操纵的控件时,它不起作用。windowsformsssynchronizationcontext
存储对控件的内部引用(通常是表单
),在该控件上调用BeginInvoke
。