根据文档,我可以从BackgroundWorker.RunWorkerCompleted事件访问UI。但根据我在控制台应用程序主线程和RunWorkerCompleted线程中的实验不同(因为线程ID不同)。这对于UI更新是不可接受的。如何解释这种情况?
static BackgroundWorker _bw = new BackgroundWorker();
static void Main(string[] args)
{
_bw.DoWork += DoWork;
_bw.WorkerReportsProgress = true;
_bw.RunWorkerAsync("hello");
_bw.RunWorkerCompleted += _bw_RunWorkerCompleted;
_bw.ProgressChanged += _bw_ProgressChanged;
Console.WriteLine("done "+ Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
private static void _bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("RunWorkerCompleated " + Thread.CurrentThread.ManagedThreadId);
}
private static void DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine(e.Argument+ " "+Thread.CurrentThread.ManagedThreadId );
}
输出:
done 1
hello 3
RunWorkerCompleated 5
答案 0 :(得分:2)
您的代码没有 UI线程。由于您没有拥有 UI线程,并且没有从调用{/ 1}} UI线程(这是知道它所必需的)什么UI线程来策划事件处理程序,它不能调用(不存在的)UI线程中的任何事件处理程序。
创建一个UI应用程序(例如winforms或WPF应用程序),确保从UI线程创建并运行BGW,然后您将看到您可以从各种事件中操纵控件(显然不是RunWorkerAsync
。
答案 1 :(得分:0)
是的,您可以从BackgroundWorker.RunWorkerCompleted访问UI,因为您有一个UI线程。
控制台应用程序在单独的线程中运行事件的原因是控制台应用程序没有SynchronizationContext。它负责管理异步操作的线程切换。