lock (new object ()) - Culto à carga ou algum “caso especial de linguagem” maluco?

87

Estou revisando um código escrito por um consultor e, embora dezenas de sinalizadores vermelhos já tenham surgido, não consigo entender o seguinte snippet:

private void foo()
{
    if (InvokeRequired)
    {
        lock (new object())
        {
            if (m_bar!= null)
                Invoke(new fooDelegate(foo), new object[] { });
        }
    }
    else
    {
        if(OnBazChanged != null)
            OnBazChanged();
    }
}

O que lock (new object ()) está fazendo aqui? Não deve ter nenhum efeito, pois está sempre travando em outro objeto, mas esse tipo de travamento é persistente em todo o código, mesmo em partes não copiadas e coladas. É algum caso especial na linguagem C # que é compilado para algo que eu não conheço, ou o programador simplesmente adotou algum culto ao cargo que funcionou algum tempo atrás?

Charles
fonte
19
Acho que eles estão muito confusos. Eles provavelmente o viram onde o new object()estava armazenado em um campo e esse campo foi usado nas lock()declarações, e eles não sabiam que era melhor não embuti-lo.
Damien_The_Unbeliever
21
Esse "consultor" tem algumas explicações a dar ... você não está errado: esse lockcódigo é totalmente inútil
Marc Gravell
12
@Baboon: Só se não for você quem tem que fazer a refatoração ...
2
Além disso, se este for WinForms, então não consigo ver por que deveria haver um bloqueio ali.
Drew Noakes de
7
Remova-o e execute novamente o seu conjunto de testes com 100% de cobertura de código. O que é isso? O consultor anterior não fez um?
Spacedman de

Respostas:

82

Eu não ficaria surpreso se fosse alguém que visse isso:

private readonly object lockObj = new object();

private void MyMethod()
{
    lock(lockObj)
    {
        // do amazing stuff, so amazing it can only run once at a time
        // e.g. comands on the Mars Rover, or programs on iOS pre 4 / 5 ??
    }
}

e pensei que poderia cortar o número de linhas.

Eu ficaria muito preocupado se fosse esse o caso ...

cjk
fonte
4
Ele pode ter visto um método chamado "newObject ()" e esse método retornou uma instância singleton, mas disse "ei, c # não tem palavras-chave para isso"?
Amiram Korach de
9
De fato, soa como um trabalho de refatoração sem entender efetivamente o que está acontecendo.
Aphelion de
1
@OrangeDog: Infelizmente, isso é impossível, pois o código em questão foi escrito antes de eu entrar para a empresa. Agora que há mudanças a serem feitas, talvez eu possa convencer a gerência a me deixar corrigir o código. Caso contrário, não assumirei a responsabilidade por quaisquer instabilidades (o último a tocar em algo é o culpado) ...
2
@Ibruder A maior prioridade seria convencer a Administração de que eles precisam de controle de versão, testes automatizados e sistemas de revisão. Se a culpa é do último a tocar em alguma coisa, então não parece uma empresa muito boa para se trabalhar.
OrangeDog de
1
Eu não me importo muito com o bloqueio obviamente quebrado - todo mundo já apontou isso, mas +1 apenas para 'ou programas no iOS pré 4/5' <g>
Martin James
15

Aqui está uma pergunta e resposta semelhante:

Os bloqueios garantem a exclusão mútua - não mais do que um thread pode segurar o bloqueio ao mesmo tempo. O bloqueio é identificado com uma instância de objeto específica. Você está criando um novo objeto para travar todas as vezes e não tem como informar a qualquer outro encadeamento para travar exatamente na mesma instância do objeto. Portanto, seu bloqueio é inútil.

JleruOHeP
fonte
2

Provavelmente é inútil. Mas existe uma chance remota de criar uma barreira de memória. Não tenho certeza se o c # bloqueia a elisão ou se preserva a semântica de ordenação do bloqueio.

benmmurphy
fonte
Foi há alguns anos, mas cara, você merece totalmente +1 por declarar este fato óbvio que algumas pessoas ignoraram completamente. Por exemplo, na Plataforma Universal do Windows não há método MemoryBarrier () e a mágica com Interlocked.CompareExchange e lock (new Object ()) tornam-se as únicas maneiras de lidar com alguns problemas.
Sergey.quixoticaxis.Ivanov
Eu nem sabia que C # permitia isso. Que bom que você apontou.
Todos de