Skip to content

Commit c4092f9

Browse files
committed
New WInDev articles Jun 2025
1 parent bf20270 commit c4092f9

File tree

2 files changed

+243
-0
lines changed

2 files changed

+243
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
layout: post
3+
title: "Cómo depurar aplicaciones WinUI 3 con herramientas del sistema operativo"
4+
author: Christian Amado
5+
date: 2025-06-04 00:00:00 -0300
6+
category: [Desarrollo de software]
7+
tags: [WinDev,Windows 11,WinUI 3]
8+
thumbnail-img: /img/posts/thumbnails/win11.png
9+
cover-img: /img/posts/cover/win11.png
10+
share_img: /img/posts/shared/windows.jpg
11+
---
12+
13+
Desarrollar aplicaciones modernas con **WinUI 3** implica más que escribir código funcional: también requiere un enfoque riguroso hacia el diagnóstico y la resolución de problemas en producción. Las aplicaciones construidas con el **Windows App SDK** pueden presentar cuellos de botella, pérdidas de memoria o bloqueos del hilo de interfaz de usuario, especialmente cuando combinan operaciones intensivas, concurrencia y bindings visuales complejos.
14+
15+
Este artículo explora un conjunto de herramientas avanzadas del sistema operativo Windows que permiten depurar, perfilar y estabilizar aplicaciones **WinUI 3** en distintos entornos. La combinación de **Event Viewer**, **Windows Performance Analyzer**, **PerfView**, y herramientas de diagnóstico de Visual Studio proporciona una visión profunda del comportamiento interno de estas aplicaciones.
16+
17+
<!--more-->
18+
19+
## Instrumentación mínima recomendada
20+
21+
Antes de comenzar cualquier depuración avanzada, la aplicación debe emitir eventos e información de diagnóstico. Algunas prácticas esenciales incluyen:
22+
23+
- Registrar excepciones no controladas en archivos de log.
24+
- Utilizar `EventSource` para emitir trazas personalizadas.
25+
- Habilitar métricas con `System.Diagnostics.Metrics` o counters personalizados.
26+
27+
Estas medidas permiten correlacionar eventos del sistema operativo con acciones específicas del usuario o de la lógica de la aplicación.
28+
29+
## Uso de Event Viewer para errores en producción
30+
31+
**Event Viewer** es la primera línea de diagnóstico en entornos donde el debugger no está disponible.
32+
33+
### Pasos recomendados:
34+
35+
1. Abrir Event Viewer (`eventvwr.msc`).
36+
2. Navegar a **Windows Logs > Application**.
37+
3. Filtrar eventos por nombre de la aplicación o ID de evento.
38+
4. Prestar atención a:
39+
- `Application Error` con `Exception code: 0xc0000005` (acceso a memoria inválido).
40+
- `Faulting module path` que apunta a bibliotecas no gestionadas.
41+
- `.NET Runtime` con detalles de excepciones CLR no controladas.
42+
43+
> En aplicaciones MSIX, también se puede consultar `Microsoft-Windows-AppModel-Runtime/Admin`.
44+
45+
## Diagnóstico con Windows Performance Analyzer (WPA)
46+
47+
**WPA**, parte del Windows Performance Toolkit, permite analizar la actividad de hilos, uso de CPU, bloqueos, y tiempos de renderizado.
48+
49+
### Escenario: bloqueo de la interfaz durante carga de datos
50+
51+
1. Ejecutar **WPR** con los perfiles `UI Delays`, `CPU Usage`, y `XAML Analysis`.
52+
2. Usar la aplicación hasta reproducir el retraso.
53+
3. Abrir el archivo `.etl` con **WPA** y examinar:
54+
- `CPU Usage (Precise)` > agrupar por hilo > buscar el UI Thread.
55+
- `XAML Parsing & Layout` para identificar cuellos de botella de renderizado.
56+
- `UI Delay Analysis` para obtener gráficos de latencia visual.
57+
58+
### Recomendación
59+
60+
Evitar operaciones síncronas pesadas en el hilo de UI. Usar `Task.Run` o `DispatcherQueue.TryEnqueue` para descargar trabajo al hilo de fondo.
61+
62+
## Análisis de memoria y fugas con PerfView
63+
64+
**PerfView** ofrece una vista detallada de las asignaciones de memoria y los tiempos de ejecución.
65+
66+
### Escenario: crecimiento progresivo de memoria
67+
68+
1. Descargar y ejecutar **PerfView**.
69+
2. Realizar una captura: `Collect > Run`, ejecutar la app y detener tras algunas acciones.
70+
3. Abrir `Heap Snapshots > Diff` para comparar uso de memoria entre dos momentos.
71+
4. Investigar objetos que permanecen anclados (`GC Root`) y posibles referencias circulares.
72+
73+
> Útil para detectar ViewModels que no se eliminan al navegar entre vistas, o listeners no removidos.
74+
75+
## Visual Studio Diagnostic Tools
76+
77+
Durante una sesión de depuración en modo Debug, Visual Studio ofrece paneles útiles:
78+
79+
- **Memory Usage**: tomar snapshots, buscar crecimiento de colecciones.
80+
- **CPU Usage**: localizar métodos intensivos en CPU.
81+
- **Events**: rastrear eventos de entrada, bindings y excepciones.
82+
- **Thread Activity**: visualizar cambios de contexto y tareas asincrónicas.
83+
84+
### Ejemplo
85+
86+
Un `ItemsRepeater` que tarda demasiado en cargar puede estar ejecutando bindings complejos en el hilo principal. Esto puede optimizarse con `x:Load` diferido o simplificando el `DataTemplate`.
87+
88+
## Captura de trazas en producción con `dotnet-trace`
89+
90+
`dotnet-trace` permite capturar trazas de eventos en tiempo de ejecución incluso fuera del depurador.
91+
92+
```bash
93+
dotnet-trace collect -p <pid> --providers Microsoft-Windows-DotNETRuntime
94+
```
95+
96+
El archivo resultante (`.nettrace`) puede analizarse con PerfView o WPA, permitiendo detectar:
97+
98+
- Recolecciones de GC anómalas.
99+
- Excepciones no visibles desde logs.
100+
- Latencia de tareas asincrónicas.
101+
102+
## Conclusión
103+
104+
Depurar una aplicación WinUI 3 de forma eficaz implica ir más allá del uso del debugger tradicional. Las herramientas del sistema operativo permiten acceder a datos detallados del comportamiento en ejecución, facilitando la identificación de problemas de rendimiento, fugas de memoria y condiciones de carrera.
105+
106+
Adoptar una estrategia de diagnóstico basada en herramientas como **WPA**, **PerfView**, **Event Viewer**, y **dotnet-trace**, no solo mejora la estabilidad de las aplicaciones, sino que eleva el estándar técnico del desarrollo en Windows.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
layout: post
3+
title: "¿Cómo ejecutar modelos de IA locales desde una app WinUI 3?"
4+
author: Christian Amado
5+
date: 2025-06-11 00:00:00 -0300
6+
category: [Desarrollo de software]
7+
tags: [WinDev,Windows 11,WinUI 3]
8+
thumbnail-img: /img/posts/thumbnails/win11.png
9+
cover-img: /img/posts/cover/win11.png
10+
share_img: /img/posts/shared/windows.jpg
11+
---
12+
13+
La inteligencia artificial está redefiniendo la experiencia del usuario en aplicaciones modernas, y las aplicaciones nativas de **Windows** no son la excepción. Gracias a **ONNX Runtime**, es posible ejecutar modelos de inferencia de manera eficiente **sin necesidad de conectarse a la nube**, lo cual es ideal para escenarios desconectados, privados o de alto rendimiento.
14+
15+
Este artículo muestra cómo integrar un modelo **ONNX** en una aplicación **WinUI 3** utilizando **.NET** y el paquete `Microsoft.ML.OnnxRuntime`. Se presentará un caso práctico de clasificación de imagenes con un modelo preentrenado.
16+
17+
<!--more-->
18+
19+
## Requisitos previos
20+
21+
- Visual Studio 2022 o superior
22+
- Windows App SDK 1.5+
23+
- Modelo ONNX (ej: SqueezeNet v1.1)
24+
- Paquetes NuGet:
25+
- `Microsoft.ML.OnnxRuntime`
26+
- `Microsoft.ML.OnnxRuntime.Managed`
27+
28+
## Paso 1: Preparar el proyecto WinUI 3
29+
30+
Crear un nuevo proyecto en Visual Studio:
31+
32+
1. Plantilla: **Blank App, Packaged (WinUI 3 in Desktop)**
33+
2. Nombre: `WinUI3ONNXDemo`
34+
3. Asegurarse de que el proyecto esté utilizando .NET 6 o superior.
35+
36+
Agregar los paquetes NuGet:
37+
```bash
38+
Install-Package Microsoft.ML.OnnxRuntime
39+
Install-Package Microsoft.ML.OnnxRuntime.Managed
40+
```
41+
42+
Agregar el modelo `.onnx` a la carpeta `Assets/Models/` del proyecto y configurar la propiedad **Copy to Output Directory** como `Copy if newer`.
43+
44+
## Paso 2: Cargar el modelo y ejecutar inferencia
45+
46+
Crear una clase de servicio para gestionar la inferencia:
47+
48+
```csharp
49+
using Microsoft.ML.OnnxRuntime;
50+
using Microsoft.ML.OnnxRuntime.Tensors;
51+
using System.Drawing;
52+
53+
public class OnnxImageClassifier
54+
{
55+
private InferenceSession _session;
56+
57+
public OnnxImageClassifier(string modelPath)
58+
{
59+
_session = new InferenceSession(modelPath);
60+
}
61+
62+
public string Classify(float[] input)
63+
{
64+
var tensor = new DenseTensor<float>(input, new[] { 1, 3, 224, 224 });
65+
var inputMeta = new NamedOnnxValue[]
66+
{
67+
NamedOnnxValue.CreateFromTensor("data", tensor)
68+
};
69+
70+
using var results = _session.Run(inputMeta);
71+
var output = results.First().AsEnumerable<float>().ToArray();
72+
var max = output.Max();
73+
var index = Array.IndexOf(output, max);
74+
75+
return $"Clase {index} - Score: {max:F3}";
76+
}
77+
}
78+
```
79+
80+
> Nota: La entrada debe estar normalizada al formato del modelo ONNX (e.g., 224x224, RGB, normalizado entre 0 y 1). Para simplificar, puede utilizarse una librería como `ImageSharp` para preparar los datos.
81+
82+
## Paso 3: Interfaz en WinUI 3
83+
84+
En `MainWindow.xaml`, incluir controles para cargar una imagen y mostrar la clasificación:
85+
86+
```xml
87+
<StackPanel Spacing="12" Padding="24">
88+
<Button Content="Seleccionar imagen" Click="OnSelectImageClicked" />
89+
<Image x:Name="PreviewImage" Width="300" Height="300" />
90+
<TextBlock x:Name="ResultText" FontSize="20" />
91+
</StackPanel>
92+
```
93+
94+
En `MainWindow.xaml.cs`:
95+
96+
```csharp
97+
private OnnxImageClassifier _classifier;
98+
99+
public MainWindow()
100+
{
101+
this.InitializeComponent();
102+
var modelPath = Path.Combine(AppContext.BaseDirectory, "Assets", "Models", "squeezenet.onnx");
103+
_classifier = new OnnxImageClassifier(modelPath);
104+
}
105+
106+
private async void OnSelectImageClicked(object sender, RoutedEventArgs e)
107+
{
108+
var picker = new FileOpenPicker();
109+
picker.FileTypeFilter.Add(".jpg");
110+
picker.FileTypeFilter.Add(".png");
111+
112+
WinRT.Interop.InitializeWithWindow.Initialize(picker, this.GetWindowHandle());
113+
var file = await picker.PickSingleFileAsync();
114+
115+
if (file != null)
116+
{
117+
using var stream = await file.OpenStreamForReadAsync();
118+
var input = PreprocessImage(stream); // convertir a float[]
119+
var result = _classifier.Classify(input);
120+
ResultText.Text = result;
121+
}
122+
}
123+
```
124+
125+
## Paso 4: Empaquetado y despliegue
126+
127+
- Incluir el modelo `.onnx` en la MSIX.
128+
- Probar en equipos sin acceso a internet.
129+
- Verificar uso de CPU o GPU dependiendo del backend de ONNX.
130+
131+
Opcionalmente, agregar soporte a DirectML o delegados personalizados para GPU.
132+
133+
## Conclusión
134+
135+
Gracias a **ONNX Runtime**, las aplicaciones **WinUI 3** pueden ejecutar modelos de inferencia localmente, lo que abre la puerta a aplicaciones de **IA** privadas, desconectadas o de bajo costo de infraestructura. Esta capacidad es particularmente poderosa en escenarios de *Edge Computing*, *kioscos*, diagnósticos offline o soluciones de accesibilidad personalizadas.
136+
137+
La combinación de **IA local + UI nativa** representa uno de los pilares del futuro del ecosistema Windows.

0 commit comments

Comments
 (0)