在UI线程上调用的方法是否需要是线程安全的?

9
如果我在UI线程上调用一个方法,它会被Windows消息队列序列化,因此不需要重新进入吗?
    private void CalledFromWorkerThread()
    {
        //changed from 'InvokeRequired' Anti-Pattern
        this.Invoke((Action) (() => _counter++; /* Is this ok? */ ));
    }

澄清:只有UI线程才会访问_counter变量。


如果你还没有这样做的话,你应该在计数器上使用锁。 - user195488
1
请参阅此处:http://www.yoda.arachsys.com/csharp/threads/winforms.shtml - user195488
3
测试 InvokeRequired 是一种反模式。Control.Invoke 已经包含了这样的检查。 - Ben Voigt
@0A0D Skeet先生在上述链接中调用的方法中没有使用锁吗?如果只有UI线程访问_counter,那么是安全的,这是我的最初的问题? - Dog Ears
是的,只要它是UI线程,你是正确的。 - user195488
3个回答

9

假设_counter只被UI线程访问,那么你现在的代码已经很好了。

如果有两个线程调用你的CalledFromWorkerThread函数,那么你所拥有的代码可以确保_counter正确地递增,并且是线程安全的。


4

根据澄清,只有UI线程访问_counter,您不需要锁。我已经更新了我的示例。我更喜欢以这种方式编码,以避免额外的if invoke required检查。

private void CalledFromWorkerThred()
{
    this.Invoke((Action) (() => _counter++; ));
}

2

它将从相同的线程委托调用,但不一定意味着您在该函数中执行的所有其他操作都是线程安全的。


假设这是唯一更改该字段的代码!它是线程安全的吗? - Dog Ears
那么它就是唯一访问它的线程(因此不需要线程安全)。所以,是的,它是安全的。 - ghimireniraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接