Pergunta

Eu notei que você pode chamar Queue.Synchronize para obter um objeto fila de thread-safe, mas o mesmo método não está disponível no Queue . Alguem sabe por quê? Parece meio estranho.

Foi útil?

Solução

Atualizar - no .NET 4, agora é ConcurrentQueue<T> em System.Collections.Concurrent, conforme documentado aqui http://msdn.microsoft.com/en-us/library/dd267265.aspx . É interessante notar que o seu método IsSynchronized (com razão) retorna false.

ConcurrentQueue<T> é um chão completo acima reescrita, a criação de cópias da fila para enumerar, e usando técnicas de não-bloqueio avançados como Interlocked.CompareExchange() e Thread.SpinWait().

O restante desta resposta é medida ainda é relevante no que se refere à morte do velho Sincronizar () e membros SyncRoot, e por que eles não funcionam muito bem do ponto de vista API.


De acordo com o comentário de Zooba, a equipe BCL decidido que muitos desenvolvedores foram mal-entendido o propósito de sincronizar (e, em menor medida, SyncRoot)

Brian Grunkemeyer descreveu esta na equipe BCL blog um par de anos atrás: http://blogs.msdn.com/bclteam/archive/ 2005/03/15 / 396399.aspx

A questão-chave é obter a granularidade correta em torno de fechaduras, onde alguns desenvolvedores seria ingenuamente usam várias propriedades ou métodos em uma coleção "sincronizados" e acreditam que seu código para ser thread-safe. Brian utiliza Queue como seu exemplo,

if (queue.Count > 0) {
    object obj = null;
    try {
        obj = queue.Dequeue();

Os desenvolvedores não iria perceber que o conde poderia ser mudado por outro segmento antes Dequeue foi invocado.

forçar os desenvolvedores a usar uma instrução de bloqueio explícita ao redor de todo os meios de operação impedindo esta falsa sensação de segurança.

Como Brian menciona, a remoção de SyncRoot foi, em parte porque, principalmente, tinha sido introduzido para apoiar Sincronizado, mas também porque, em muitos casos, há uma melhor escolha de objeto de bloqueio - na maioria das vezes, seja a instância de fila em si, ou um

private static object lockObjForQueueOperations = new object();

na classe possuir a instância da Queue ...

Esta última abordagem é geralmente mais seguro, pois evita algumas outras armadilhas comuns:

Como se costuma dizer, rosqueamento é difícil , e fazendo parecer fácil pode ser perigoso.

Outras dicas

Você pode achar o valor CTP paralela verificando; aqui está uma entrada de blog dos caras que estão colocando-lo juntos que é muito tópica:

Enumerar simultâneas coleções

Não é bem a mesma coisa, mas pode resolver o seu problema maior. (Eles ainda usam Queue<T> contra ConcurrentQueue<T> como exemplo.)

Há um agora, em .Net 4.0:

ConcurrentQueue<T> 

em System.Collections.Concurrent

http://msdn.microsoft.com/en-us/library/ dd267265.aspx

(Eu suponho que você quer dizer Queue para o segundo.)

Eu não posso responder especificamente a questão, a não ser que as propriedades IsSynchronized e SyncRoot (mas não sincroniza () explicitamente) são herdados a partir da interface ICollection. Nenhuma das coleções genéricas usar este eo ICollection interfaces não inclui SyncRoot.

Quanto ao porquê de ele não está incluído, só posso especular que eles não estavam sendo usados ??tanto na forma pretendida pelos designers de biblioteca ou eles simplesmente não estavam sendo bastante usada para justificar retê-los nas coleções mais recentes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top