我可以在 WPF 中使用 Monitor.Enter/Exit (c# lock) 而不必担心重入错误吗?
如果我在 WPF 应用程序中使用 Monitor.Enter/Exit(通过 C# 锁定语法),调度程序会导致重新进入吗?
在下面的示例中,假设当文本框中的文本发生更改时调用 OnTextChanged,是否会错误地调用 _worker.RunWorkerAsync() ?
public class SomeClass
{
private object _locker = new object();
private bool _running = false;
private BackgroundWorker _worker;
public void SomeClass()
{
// initialize worker...
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lock (_locker)
_running = false;
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
// ... do something time consuming ...
}
private void OnTextChanged()
{
lock(_locker)
{
if (!_running)
{
_worker.RunWorkerAsync();
_running = true;
}
}
}
}
我相信这是可能的,但我无法重现这一点。 WPF 是否以某种方式阻止调度程序在等待监视器时调用等待任务?
If I use Monitor.Enter/Exit (through the c# lock syntax) in a WPF application, can the dispatcher cause re-entrance?
In the sample below, presuming OnTextChanged is called when the text in a textbox changes, could the call to _worker.RunWorkerAsync() be called incorrectly?
public class SomeClass
{
private object _locker = new object();
private bool _running = false;
private BackgroundWorker _worker;
public void SomeClass()
{
// initialize worker...
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lock (_locker)
_running = false;
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
// ... do something time consuming ...
}
private void OnTextChanged()
{
lock(_locker)
{
if (!_running)
{
_worker.RunWorkerAsync();
_running = true;
}
}
}
}
I believe it's possible, but I've not been able to reproduce this. Does WPF somehow prevent the dispatcher from invoking waiting tasks when waiting on monitor?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不确定你害怕什么。 OnTextChanged 和 RunWorkerCompleted 都在 UI 线程上运行。它不会是可重入的,你也不需要锁。这两种方法都只能在 UI 线程空闲时开始运行,从而推动消息循环。
Not sure what you fear. Both OnTextChanged and RunWorkerCompleted run on the UI thread. It won't be re-entrant, you don't need the lock either. Either method can only start running when the UI thread is idle, pumping the message loop.
虽然与您的问题没有直接关系,但如果您不将_running
标记为volatile
.实际上这并不完全正确,因为您没有使用双重检查锁。无论如何,我把与 volatile 相关的信息留在那里,供你参考。
While not directly related to your question, you could run into register caching issues if you don't mark_running
asvolatile
.Actually this isn't strictly true, as you are not using a double-checked lock. I've left the information related to volatile there anyway, for your reference.