Desenvolvimento

2 jan, 2012

Como rastrear objetos fora do escopo no Visual Studio Debugger na depuração?

Publicidade

Neste artigo, explicarei como podemos rastrear um objeto que já está fora do escopo criando um Object ID enquanto se faz a depuração. 

Ao utilizar a opção “Make Object ID”, estamos informando ao Visual Studio Debugger para manter o rastreamento daquele objeto, independentemente de ele estar dentro ou fora do escopo do contexto atual. Podemos criar o Object ID a partir de Locals, Autos ou Watch Windows. O Object ID é um número inteiro seguido por um (#). Quando criamos um Object ID para um objeto em particular, o Visual Studio Debugger (CLR Debugging Services) usa um valor inteiro para unicamente identificar o objeto. Esse Object ID permite que você obtenha os detalhes do objeto mesmo se ele esteja fora do escopo. 

Vamos explorar isso com a ajuda do bloco de código abaixo:

01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05
06 namespace CreateObjectIDDemoApps
07 {
08 class Program
09 {
10 static void Main(string[] args)
11 {
12 List<Student> students = new List<Student> {
13 new Student { Roll = 1, Name = "Abhijit", Address = "Hyderabad" },
14 new Student { Roll = 2, Name = "Kunal", Address = "Pune" },
15 new Student { Roll = 3, Name = "Abhishek", Address = "Kolkata" },
16 new Student { Roll = 4, Name = "Rahul", Address = "Delhi" }
17 };
18
19 foreach (Student stud in students)
20 {
21 Console.Write(stud.ToString());
22 }
23 }
24
25 class Student
26 {
27 public int Roll { get; set; }
28 public string Name { get; set; }
29 public string Address { get; set; }
30 public override string ToString()
31 {
32 return "Roll : " + this.Roll.ToString() + "\tName : " + this.Name + "\tAddress : " + this.Address + "\n";
33 }
34 }
35 }
36 }

De acordo com o código acima, temos uma lista do objeto Student. Irei mostrar como podemos criar um novo Object ID para qualquer objeto específico e rastreá-lo mesmo fora do escopo.

Criando um Object ID

Para criar um Object ID, você tem que visualizar o objeto a partir da Watch Window, então clique com o botão direito > Context Menu e selecione “Make Object ID”.

A watch window irá mostrar um número com o sinal (#).

O número do Object ID será incrementado baseado na criação do Object ID. O que significa que para o próximo Object ID o número de identificação será 2#, 3# etc.

Usando o Object ID

Você já criou o Object ID (1#) para um objeto student em particular a partir de uma lista de objetos Student. Vamos dar uma olhada em como usar esse Object ID. Você pode facilmente digitar o Object ID na watch window para obter os detalhes do valor daquele objeto.

Então, a partir da imagem acima, você pode ver o Object ID 1# mostrando os detalhes do objeto student com Roll= 1, para o qual nós criamos aquele Object ID.

Se você olhar os detalhes, você pode ver, apesar de o ponto de parada atual mostrar os detalhes do student com Roll=3, o 1# Object ID apontando para o Objeto Student com Roll 1, devido ao fato de o Object ID 1# ainda unicamente estar identificando um dos objetos student.

Criando e usando Object ID para objetos múltiplos

Você pode criar e usar Object IDs múltiplos usando os mesmos processos que já discuti. Se você quiser rastrear mais de um objeto, você pode usá-lo.

Quando um objeto sai do escopo?

Até agora, eu discuti como criar um Object ID e como usá-lo. Agora vamos discutir sobre o uso real do Object ID. Como eu já disse, “O Object Id é usado para rastrear qualquer objeto, mesmo se o objeto estiver fora do escopo”. No meu exemplo acima, ambos o Object ID e o objeto atual estavam no escopo do contexto atual. Vamos dar uma olhada quando o objeto sai de escopo e qual o comportamento do Object ID nesse momento.

Para explorar isso, apenas coloque o ponto de parada fora do escopo do foreach, onde o objeto “stud” não está no escopo. Rode a aplicação e crie um Object ID para o primeiro objeto nas listas student. Espere até que o depurador atinja o ponto de parada perto do foreach.

A imagem acima é um rápido resumo do rastreamento do objeto quando ele sai do escopo. A partir da imagem, você pode ver que o objeto “Stud” não está sendo avaliado como se não tivesse no escopo atual, mas o Object ID (1#) ainda está ativo, o que mostra os valores reais do objeto para o qual ID foi criado. Você também pode clicar no ícone  Refresh” com os valores do objeto “Stud” para obter o valor atualizado. Mas, se você clicar nesse ícone, você receberá a mensagem “The name ‘stud’ does not exist in the current context” (O nome stud não existe no contexto atual, em tradução livre), como mostrado abaixo.

Mas você pode obter os mesmos valores de objeto a partir do Object ID. Apesar se deu objeto real estar fora do escopo e não ser coletado pelo GC, o Object ID ainda rastreia esse objeto, uma vez que o objeto ainda está presente na memória. Você receberá a mensagem “Can’t evaluated object”, uma vez que o objeto real seja coletado pelo GC.

Trabalhando com um objeto “fora do escopo”?

Você pode acessar qualquer variável ou método a partir do ID de um objeto como ((ClassName)ObjectID#).Properties ou ((ClassName)ObjectID#).Method(). A partir do nosso exemplo, podemos acessar o Roll para esse objeto, como mostrado abaixo.

Da mesma maneira, podemos acessar as mesmas variáveis através da “Immediate Window”.

Conditional de parada com Object ID

Você também pode criar pontos de parada condicionais com os IDs de objetos criados. Eu expliquei sobre como utilizar pontos de parada condicionais no artigo Mastering in Visual Studio 2010 Debugging – Conditional Breakpoint. Temos que usar a mesma maneira que mencionei quando discuti sobre o acesso ao Object ID.

As condições acima dizem ao Visual Studio Debugger que, se o Object ID 1# tendo Roll =1, eles somente acionam o ponto de parada.

Nota: Ao usar o ponto de parada condicional, você tem que se certificar de que está criando o Object ID antes de o depurador acionar os pontos de parada condicionais. Caso contrário, você terá a mensagem de erro “Object ID not found” (Objeto não encontrado), como mostrado abaixo.

Deletando um Object ID

Você pode deletar o objeto usando uma maneira parecida com a que usamos para criar um Object ID. Clique com o botão direito na instância do objeto para o qual você já tenha criado o Object ID, você terá a opção “Delete Object ID”.

Se você deletar o Object ID com um número específico, isso não não quer dizer que o próximo ID criado tenha o mesmo ID que você deletou. O que significa, digamos, se você tem 3 Object ID’s 1#, 2# e 3#, e você deletou o Object ID 2#. Agora, se você criar outro novo Object ID, seu novo ID será 4# não 2#. Isso indica que um Object ID é usado para unicamente identificar uma instência particular do objeto, não para o mesmo objeto mais uma vez ou para outro objeto. O mesmo ID somente pode ser usado uma vez, porque o GC coleta esse objeto.

Espero que este artigo ajude você! 

?

Texto original disponível em http://abhijitjana.net/2010/10/20/how-to-track-an-object-which-is-out-of-scope-while-debugging/