/// <summary> /// Copia o escopo informado para <see cref="Escopo.Atual"/> /// </summary> /// <remarks> /// Geralmente usado em casos onde o escopo atual é usado em outras Threads para aproveitar /// a mesma transacao por exemplo. /// </remarks> /// <param name="escopo"></param> public Escopo(Escopo escopo) { if (escopo.EstaFinalizado) throw new ObjectDisposedException("Não posso inicializar um escopo a partir de outro escopo finalizado"); if (escopo == null) throw new NullReferenceException(); this.AtribuirEscopoAtual(); }
public override SiteMapNode BuildSiteMap() { if (EhParaConstruirSiteMap()) { Clear(); _NoRaiz = new SiteMapNode(this, Guid.NewGuid().ToString(), "~/", String.Empty); _NoRaiz.Roles = new string[] { "*" }; AddNode(_NoRaiz); bool acessoViaInternet = AuthenticationTicket.Atual.AcessoViaInternet; NosSiteMapDataSet nosSiteMapDataSet; using (Escopo escopo = new Escopo()) { nosSiteMapDataSet = ConstruirSiteNodes(); } MapearNosSiteMapDataSetParaSiteMapNode(nosSiteMapDataSet, acessoViaInternet); this._RebuildSiteMap = false; } return this._NoRaiz; }
/// <summary> /// Faz atribuicao do escopo atual com o valor desta instancia /// </summary> private void AtribuirEscopoAtual() { // Ordem de atribuicao inicial é importante em caso de erro! // _EscopoAnterior primeiro assegura que nos saberemos que nós precisamos restaurar // _EstaFinalizado segundo, para termos certeza de que nos nao faremos dispose ate nós estarmos tão próximos // quanto possível para fazermos uma configuração correta (leia todos os outros campos sao setados antes de // _EstaFinalizado possuir valor null // __Atual finalmente, para termos certeza de que thread static possuem apenas objetos validos _EscopoAnterior = _Atual; _MarcadoComoCompleto = false; _Atual = this; this.ContadorEscopo = 1; }
/// <summary> /// /// </summary> /// <param name="disposing"></param> protected override void Dispose(bool disposing) { bool possoFinalizar = !EstaFinalizado && disposing && --(Atual.ContadorEscopo) < 1; if (possoFinalizar) { bool marcadoComoCompleto = MarcadoComoCompleto; // Primeiro, remover esta instancia da fila (mas, apenas se nos somos o atual da fila e se nosso // contador de escopos indicar que somos o primeiro criado) // Nota: Thread-local _Atual, e requerimento de que o escopo nao sofra dispose em outras threads // significam que podemos dispensar o lock. if (_Atual == this) { // Caso o usuario tenha chamado dispose fora de ordem, retorna na fila // ate encontrar objetos que nao tenham sido finalizados (chamada a dispose). Escopo anterior = _EscopoAnterior; while (anterior != null && anterior.EstaFinalizado) { anterior = anterior._EscopoAnterior; } _Atual = anterior; } // segundo, marcar nosso estado interno como finalizado ContextoAcessoDado contextoAcessoDado = _ContextoAcessoDado; _ContextoAcessoDado = null; // Por ultimo, limpar os escopos de dados mantidos por mim FinalizarContextoAcessoDado(contextoAcessoDado, marcadoComoCompleto); } base.Dispose(disposing); }