Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)
Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)

🔧 Programmierung 🕛 vor 1 Monat 12 Min Lesezeit
0

Deja de Entrecerrar los Ojos con los Stack Traces de .NET: Depúralos con Claude en Visual Studio

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Deja de Entrecerrar los Ojos con los Stack Traces de .NET: Depúralos con Claude en Visual Studio



Salta una excepción no controlada y Visual Studio te suelta cuarenta líneas de stack trace en el regazo. Treinta y ocho viven en Microsoft.EntityFrameworkCore.* o en System.Private.CoreLib, una es un frame de máquina de estados asíncrona con un nombre tipo <<Main>$>b__0_0, y exactamente una apunta a código que escribiste tú. Tu trabajo es encontrar esa línea, entender por qué explotó y arreglar la causa real — no el síntoma.



Todos hemos pegado un trace en el buscador y recibido a cambio una sola pregunta de Stack Overflow de 2015, cero respuestas, y un único comentario que dice "¿al final lo resolviste?". Hay una forma mejor, y ahora vive dentro de Visual Studio: le pasas el trace a Claude y recibes un diagnóstico ordenado por probabilidad, atado a tu línea, con un arreglo que de verdad puedes razonar.











Dos Formas de Meter a Claude Dentro de Visual Studio



No necesitas salir del IDE ni pegar nada en un navegador. Hay dos caminos sólidos, y cada uno sirve para un momento distinto.






1. Copilot Chat con un modelo Claude (dentro del IDE, conversacional)



Visual Studio 2022 (17.14+) trae GitHub Copilot con un selector de modelo. Haz clic en el badge de Copilot, abre el desplegable de modelos en la caja del chat y elige un modelo Claude — Sonnet para el diagnóstico rápido del día a día, Opus cuando el bug es realmente feo. A partir de ahí, cada respuesta de Copilot Chat la genera Claude.



Dos cosas hacen que este camino brille para depurar:




  • Cuando una excepción no controlada abre el Asistente de excepciones durante el debug, hay un enlace Preguntar a Copilot justo en ese diálogo. Con Claude seleccionado como modelo, ese análisis de un clic corre sobre Claude.

  • En la caja del chat puedes traer contexto real con referencias ##Program.cs, #solution, o una selección resaltada — para que Claude lea tu código de verdad, no una paráfrasis.



Si prefieres usar tu propia clave de Anthropic en vez de los modelos de Copilot, el mismo selector tiene Manage Models → agregar Anthropic → pegar tu API key. Cómodo si ya pagas por acceso a la API.






2. Claude Code en la terminal integrada (agéntico)



Todavía no hay una extensión oficial de Claude Code para el Visual Studio completo, pero no la necesitas — Claude Code corre en cualquier terminal, incluida Ver → Terminal (Ctrl+) dentro de VS. Ejecutaclaude`, pega el trace y, como Claude Code puede leer todo el repositorio, abrirá él mismo el archivo culpable, seguirá la ruta de llamadas y propondrá el arreglo como un diff que apruebas o rechazas.



El intercambio es simple: Copilot Chat es más rápido para un "¿qué significa esto?", mientras que Claude Code es mejor cuando el arreglo toca varios archivos o quieres que reproduzca y verifique. Usa el que el bug se merezca.











Un Ejemplo Real: El Trace de EF Core Que Culpa a Quien No Es



Depuremos algo concreto. Este es un endpoint de minimal API en .NET 10 que devuelve el resumen de pedidos de un cliente. Se ve razonable, y compila sin quejas:



`csharp

// Program.cs — minimal API en .NET 10

using Microsoft.EntityFrameworkCore;



var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext(o => o.UseSqlite("Data Source=shop.db"));



var app = builder.Build();



app.MapGet("/orders/{customerId:int}/summary", async (int customerId, ShopContext db) =>

{

// Disparamos ambas consultas "en paralelo" para ir rápido — ¿verdad?

var ordersTask = db.Orders.Where(o => o.CustomerId == customerId).ToListAsync();

var totalTask = db.Orders.Where(o => o.CustomerId == customerId).SumAsync(o => o.Total);




CODE
await Task.WhenAll(ordersTask, totalTask);

return Results.Ok(new { Orders = ordersTask.Result, Total = totalTask.Result });




});



app.Run();

`



Llamas al endpoint y lanza. Este es el trace que muestra Visual Studio (recortado a los frames que aparecen):



text

System.InvalidOperationException: A second operation was started on this context

instance before a previous operation completed. This is usually caused by different

threads concurrently using the same instance of DbContext. For more information on

how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken ct)

at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken ct)

at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable
1 source, CancellationToken ct)

at Program.<>c.<

$>b__0_0(Int32 customerId, ShopContext db) in C:\src\Shop.Api\Program.cs:line 12

`

Cuatro de esos cinco frames son internos de EF Core. El único que es tuyo — Program.cs:line 12 — es la llamada a ToListAsync(), lo que hace parecer que ToListAsync es el villano. No lo es.






Cómo pasárselo a Claude bien



La calidad de la respuesta depende por completo de lo que pegues. Un mensaje de una línea te da una conjetura de una línea. Dale a Claude el panorama completo:



`text

.NET 10, EF Core 10, SQLite. Este endpoint lanza en cada request con carga normal

(no solo con concurrencia). Abajo van la excepción completa y el código del endpoint —

¿cuál es la causa raíz y cuál es el arreglo idiomático?



[pega la excepción COMPLETA con ex.ToString() — mensaje + todas las inner exceptions + trace]



[pega el handler del MapGet]

`



Tres cosas hacen que ese prompt sea bueno:





  1. La excepción completa, no el titular. ex.ToString() incluye cada inner exception y el trace entero. En Copilot Chat, #Program.cs te trae el código solo.


  2. El primer frame que es tuyo. Apunta a Claude a Program.cs:line 12 y al código a su alrededor. Los frames de framework son contexto; tu frame es la escena del crimen.


  3. Las condiciones. "En cada request" vs "solo bajo carga" vs "intermitente" cambia el diagnóstico por completo. Di lo que observaste.






Lo que Claude te responde



En vez de "la línea 12 falló", obtienes el mecanismo real: el DbContext de EF Core no es thread-safe y no permite dos operaciones sobre la misma instancia a la vez. Task.WhenAll arranca la segunda consulta antes de que termine la primera, ambas sobre el mismo db inyectado, y el ConcurrencyDetector de EF lanza. El número de línea era una pista falsa — el bug es el patrón, no la llamada.



Y te da los dos arreglos, con el intercambio incluido:



csharp

// Arreglo A — el más simple: ejecútalas en secuencia. Un contexto, una operación a la vez.

var orders = await db.Orders.Where(o => o.CustomerId == customerId).ToListAsync();

var total = await db.Orders.Where(o => o.CustomerId == customerId).SumAsync(o => o.Total);

return Results.Ok(new { Orders = orders, Total = total });



`csharp

// Arreglo B — paralelismo real: dale a cada consulta su PROPIO contexto vía factory.

builder.Services.AddDbContextFactory(o => o.UseSqlite("Data Source=shop.db"));



app.MapGet("/orders/{customerId:int}/summary",

async (int customerId, IDbContextFactory factory) =>

{

await using var ordersDb = await factory.CreateDbContextAsync();

await using var totalDb = await factory.CreateDbContextAsync();



CODE
var ordersTask = ordersDb.Orders.Where(o => o.CustomerId == customerId).ToListAsync();
var totalTask = totalDb.Orders.Where(o => o.CustomerId == customerId).SumAsync(o => o.Total);

await Task.WhenAll(ordersTask, totalTask);
return Results.Ok(new { Orders = await ordersTask, Total = await totalTask });


});

`



El Arreglo A es lo que quieres el 90% de las veces — dos consultas a SQLite son rápidas, y el paralelismo nunca valió el bug. El Arreglo B es la respuesta cuando las consultas son genuinamente lentas e independientes, porque IDbContextFactory<T> te entrega un contexto fresco y de vida corta por operación. Esa distinción — no el número de línea — es lo que de verdad te faltaba, y es el tipo de criterio que te da una buena explicación y no un resultado de búsqueda.



Un stack trace asíncrono de .NET tiene dos tipos de frames: los cuarenta que le pertenecen al runtime, y el que es culpa tuya. El trabajo de Claude es saltarse los cuarenta y explicarte el uno.









Verifica — No Confíes a Ciegas



Claude es un colega senior muy rápido que de vez en cuando se equivoca con toda seguridad. Trata su diagnóstico como una hipótesis fuerte, no como un veredicto:





  • Reproduce y confirma. Aplica el arreglo, vuelve a correr y comprueba que la excepción de verdad desapareció — idealmente bajo las mismas condiciones que la dispararon. En Visual Studio, pon un breakpoint en la línea corregida y observa el estado.


  • Pregunta el por qué, no solo el qué. "Explica por qué esto lo arregla" saca a la luz una causa raíz equivocada rapidísimo. Si el razonamiento no se sostiene, el arreglo probablemente tampoco.


  • Ojo con las causas plausibles pero falsas. Sobre todo con bugs intermitentes, Claude puede proponer una causa que encaja con el trace pero que no es la tuya. Haz que ordene los candidatos y te diga cómo distinguirlos.



El debugger sigue siendo el dueño del estado. Claude es dueño del significado. Cuando necesitas saber el valor real de una variable en el momento del crash, eso es una ventana de inspección y un breakpoint, no un prompt de chat.









Cuándo Recurrir a Claude — y Cuándo No



Recurre a él cuando:




  • El tipo o el mensaje de la excepción te resulta desconocido, o el trace es casi todo internos de framework.

  • La causa real está enterrada en inner exceptions o en un AggregateException.

  • Estás mirando frames asíncronos y no logras saber cuál de tus líneas es el origen.

  • Quieres el arreglo idiomático y sus intercambios, no solo un parche que quite el rojo.



No te molestes cuando:




  • Ya sabes la causa — un NullReferenceException en una línea que acabas de escribir no necesita un LLM.

  • Necesitas el valor en runtime de algo — usa el debugger.

  • El trace contiene secretos o datos de clientes. Las cadenas de conexión, los tokens y los datos personales aparecen en mensajes de excepción y payloads más seguido de lo que te gustaría. Límpialos antes de pegar, especialmente con un modelo en la nube.



La regla de oro: si de otro modo abrirías el navegador para buscar la excepción, mejor pregúntale a Claude — está en el IDE, puede leer tu código, y no te mandará a un hilo de foro muerto de 2015.









Puntos Clave





  • El trace muestra maquinaria, no intención — máquinas de estados asíncronas, inner exceptions y frames de framework entierran la única línea que es tuya. Leer traces es reconocimiento de patrones, que es justo donde ayuda un LLM.


  • Claude vive en Visual Studio de dos formas — elígelo en el selector de modelo de Copilot Chat para diagnóstico rápido y conversacional; corre Claude Code en la terminal integrada cuando el arreglo es agéntico y abarca varios archivos.


  • El contexto lo es todo — pega el ex.ToString() completo, apunta al primer frame que es tuyo y describe cuándo pasa. Un mensaje titular recibe una conjetura titular.


  • El número de línea suele ser una pista falsa — el ejemplo de EF Core lanza en ToListAsync, pero el bug es compartir un DbContext entre consultas paralelas. El valor está en la explicación, no en la ubicación.


  • Verifica, luego confía — reproduce el arreglo, pregunta por qué funciona y nunca pegues secretos. El debugger es dueño del estado; Claude, del significado.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
Use custom web fonts in Google Sheets charts
2 Quellen
Introducing the new 1Password App for Google Chat
1 Quelle
Context-aware access controls are available for Gemini Enterprise in the Admin console
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Deja de Entrecerrar los Ojos con los Stack Traces de .NET: Depúralos con Claude en Visual Studio

Thematisch verwandte Begriffe: Deja, Entrecerrar, Ojos, Stack · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...