带有调度程序的BackgroundWorker似乎没有做任何事情
我正在尝试更新绑定到 UI 的数据的 ObservableCollection
。我知道要做到这一点,我需要使用 Dispatcher
和 BeginvInvoke()
,并使用BackgroundWorker 是一个很好的方法。无论如何,我已经编译并运行了所有这些,但没有任何反应。我需要每 2 分钟左右更新一次 UI,所以我还使用了 DispatcherTimer
这很有效,因为 DispatcherTimer 是 Dispatcher 的一部分,但会冻结 UI:
DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();
private void dispTimer_Tick(object sender, EventArgs e)
{
PartialEmployees.Clear();
}
因此,使用 BackgroundWorker 我将其拼凑在一起:
DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();
private void dispTimer_Tick(object sender, EventArgs e)
{
BackgroundWorker _worker = new BackgroundWorker();
_worker.DoWork += DoWork;
_worker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher.CurrentDispatcher.BeginInvoke( new Action(()=>
{
PartialEmployees.Clear();
}));
}
但用户界面没有任何反应。我错过了什么/做得不正确吗?
I am trying to update an ObservableCollection
that is data bound to the UI. I know that to do this I need to use Dispatcher
and BeginvInvoke()
, and to make it so that the UI doesn't freeze up when I do so, using a BackgroundWorker is a good way to go about it. In any event, I have all this, compiled and running, but nothing happens. I need to update the UI every 2 minutes or so, so I am also using a DispatcherTimer
This works, because DispatcherTimer is part of Dispatcher, but freezes the UI:
DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();
private void dispTimer_Tick(object sender, EventArgs e)
{
PartialEmployees.Clear();
}
So, using the BackgroundWorker I pieced together this:
DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();
private void dispTimer_Tick(object sender, EventArgs e)
{
BackgroundWorker _worker = new BackgroundWorker();
_worker.DoWork += DoWork;
_worker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher.CurrentDispatcher.BeginInvoke( new Action(()=>
{
PartialEmployees.Clear();
}));
}
But nothing happens to the UI. What am I missing/not doing correctly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您有两个问题:
当您从后台线程使用
Dispatcher.CurrentDispatcher
时,它获取的是后台线程的 Dispatcher,而不是 UI 线程的 Dispatcher。根据您的描述,我了解到您的
PartialEmployees.Clear()
方法需要大量时间来执行,并且您希望避免在执行期间锁定 UI 线程。但是,让 BackgroundWorker 在 UI 线程上调用PartialEmployees.Clear()
与使用 DispatcherTimer 具有相同的效果,因此您需要一种与您想要的解决方案不同的解决方案。如果您只想修复 Dispatcher.CurrentDispatcher 问题,只需将当前 Dispatcher 存储在本地变量中,如下所示:
这将导致您的 UI 更改生效,但在更改期间它仍然会锁定 UI,就像您没有更改一样使用BackgroundWorker。原因是:
因此,您的行为与 DispatcherTimer 回调直接调用 PartialEmployees.Clear() 相同:在每种情况下,耗时的操作都在 UI 线程上执行。
锁定的原因是,每当您在 UI 线程上执行大量工作时,您都会在运行时遇到短暂的锁定。解决方案是将您的工作分成更小的部分,并通过 DispatcherTimer 或 BackgroundWorker 一次完成一个部分。对于您的情况,请检查
PartialEmployees.Clear()
的代码,看看是否可以增量完成。You have two problems:
When you use
Dispatcher.CurrentDispatcher
from the background thread, it is getting the background thread's Dispatcher, not the UI thread's Dispatcher.From your description I gather that your
PartialEmployees.Clear()
method takes significant time to execute and you want to avoid locking the UI thread during the execution. However, having a BackgroundWorker invokePartialEmployees.Clear()
on your UI thread will have the same effect as using the DispatcherTimer, so you need a different solution than the one you are going for.If you only want to fix the Dispatcher.CurrentDispatcher problem, just store the current Dispatcher in a local variable like this:
This will cause your UI change to work but it will still lock up the UI during the change, exactly as if you had not used BackgroundWorker. The reason for this is:
So your behavior is the same as if the DispatcherTimer callback had called PartialEmployees.Clear() directly: In each case the time-consuming operation is executed on the UI thread.
The reason for the lockup is that any time you do a large piece of work on the UI thread you will get a momentary lockup while it runs. The solution is to break your work into smaller portions and do them one at a time, either from a DispatcherTimer or a BackgroundWorker. In your case, examine the code for
PartialEmployees.Clear()
to see if it can be done incrementally.这里的问题是您正在使用后台线程中的方法
Dispatcher.CurrentDispatcher
。您需要的是 UI 线程的 Dispatcher 实例。The problem here is that you're using the method
Dispatcher.CurrentDispatcher
from the back ground thread. What you need is theDispatcher
instance for the UI thread.我认为您不需要后台工作,因为
Dispatcher
上的BeginInvoke
在线程池线程上运行。像这样的东西应该有效,并且更简洁
I dont think you need the background work, as
BeginInvoke
on theDispatcher
runs on a Threadpool thread.something like this should work, and is more succinct