我可以在 WPF 中使用 Monitor.Enter/Exit (c# lock) 而不必担心重入错误吗?

发布于 2024-10-09 17:25:57 字数 938 浏览 0 评论 0原文

如果我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

删除会话 2024-10-16 17:25:57

不确定你害怕什么。 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.

白芷 2024-10-16 17:25:57

虽然与您的问题没有直接关系,但如果您不将 _running 标记为 volatile.

实际上这并不完全正确,因为您没有使用双重检查锁。无论如何,我把与 volatile 相关的信息留在那里,供你参考。

While not directly related to your question, you could run into register caching issues if you don't mark _running as volatile.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文