Estoy trabajando en una base de código muy grande y antigua de una aplicación winform de escritorio. En esta base de código hay muchas operaciones realizadas en subprocesos en segundo plano, principalmente utilizando BackgroundWorker .
Un patrón común en esta base de código es ocultar la complejidad vinculando artefactos al subproceso que se está ejecutando. Por ejemplo, la conexión y la transacción de la base de datos se almacenan en campos [ThreadStatic] .
Estoy tratando de cambiar esto y comenzar a usar el código async/await , y beneficiarme de ejecutar la tarea en cualquier subproceso del grupo y permitir que una tarea continúe ejecutándose en cualquier otro subproceso mediante ConfigureAwait(false) . Sé que [ThreadStatic] no funciona bien con async/await , y he leído varias respuestas aquí que sugieren usar AsyncLocal<T> en su lugar.
Dado que estoy trabajando en una gran base de código, como se mencionó anteriormente, no puedo cambiar a async/await en todas partes de una sola vez, y debo hacer estos cambios gradualmente. Entonces, el código que antes tenía [ThreadStatic] cambiará a AsyncLocal<T> , pero gran parte del código continuará usando BackgroundWorker y no alcanzará una sola línea de código async/await .
Pregunta
esto funcionara? Necesito poder definir algún tipo de flujo de contexto que funcione con mi nuevo código async/await , y también seguir trabajando con mi antiguo código no asíncrono que dependía de [ThreadStatic] manteniendo cada subproceso independiente entre sí.
Si estoy totalmente equivocado y voy por el camino equivocado, las sugerencias son muy bienvenidas.
Deberia de funcionar.
AsyncLocal<T> es una abstracción del contexto de llamada lógica. Describo el contexto de la llamada lógica y cómo interactúa con async / await en detalle en una publicación de blog anterior.
En resumen, probablemente funcionará bien, pero hay un aspecto de AsyncLocal<T> que es bastante diferente a ThreadStatic .
Cuando escribe en el AsyncLocal<T> , ese valor se establece para el contexto de llamada lógica actual. Un método async establecerá un ámbito de copia en escritura para su contexto de llamada lógica, por lo que si escribe en él dentro de un método async , creará un nuevo contexto de llamada lógica que contiene el nuevo valor. Esto permite que el método async lo use de forma anidada, donde los contextos "internos" pueden sobrescribir los contextos "externos". Sin embargo, los valores del contexto "interno" nunca regresan a la persona que llama; cuando se reanuda el contexto "externo", reemplaza completamente el contexto "interno".
Si ninguno de los métodos es async y los valores solo se establecen desde sus propios subprocesos, entonces ese subproceso solo tiene un único contexto de llamada lógico, y escribir/leer los valores funcionará igual que ThreadStatic .