c# - net - Acceda a HttpContext.Current desde diferentes hilos
session c# mvc (5)
Tengo una aplicación C # ASP.NET que inicia aproximadamente 25 subprocesos diferentes ejecutando algunos métodos en una clase llamada SiteCrawler.cs.
En HttpContext.Current.Session
, deseo guardar el resultado de la búsqueda realizada por el usuario y presentarlo al usuario cuando todos los hilos terminen de ejecutarse. Mi problema es que el objeto HttpContext.Current
es nulo en los hilos engendrados porque no existe allí.
¿Qué otras opciones tengo para guardar los datos específicos del usuario / sesión sin usar la sesión debido a las limitaciones cuando la aplicación es multiproceso?
He intentado buscar cada pulgada de Stackoverflow para encontrar una solución pero sin suerte ...
@Rory hizo un comentario arriba, que ciertos objetos en el HttpContext
se volverán nulos incluso si los pasas al hilo. Esto me pasó con la propiedad de User
. Entonces, en su lugar, puede copiar el usuario al hilo CurrentPrincipal de esta manera:
En el contexto del controlador, guarde el usuario:
_user = HttpContext.Current.User;
var processThread = new Thread(() => ThreadedCode());
processThread.Start();
En el hilo, configure el usuario ''Thread''s'':
private static void ThreadedCode()
{
// Workaround for HttpContext.Current.User being null.
// Needed for CreatedBy and RevisedBy.
Thread.CurrentPrincipal = _user;
Tenga en cuenta que HttpContext solo estará disponible durante la vigencia de la solicitud. El hilo continuará en vigencia mucho más tiempo que la solicitud, ¡que probablemente es la razón por la que necesitas un hilo en primer lugar! :)
Eche un vistazo a este artículo de Fritz Onion: Use Threads y Build Asynchronous Handlers en su código web del lado del servidor . Es bastante largo, pero su requisito no es demasiado trivial.
También K. Scott Allen publicó un artículo algo más breve sobre este mismo tema: Working With HttpContext.Current
En mi aplicación hay muchos códigos que usan HttpContext.Current
y no puedo modificar ese código.
worker.DoWork()
del ejemplo siguiente utiliza ese código. Y tuve que ejecutarlo en un hilo separado.
Llegué a la siguiente solución:
HttpContext ctx = HttpContext.Current;
Thread t = new Thread(new ThreadStart(() =>
{
HttpContext.Current = ctx;
worker.DoWork();
}));
t.Start();
// [... do other job ...]
t.Join();
Puede guardarlo en la base de datos y luego, puede dejar que el navegador del usuario continúe actualizando o usando ajax o usando el nuevo señalizador para verificar si el resultado ya está escrito en db. Espero eso ayude.
Simplemente agregue el HttpContext.Current al constructor de su clase SiteCrawler.cs
public class SiteCrawler
{
HttpContext context = HttpContext.Current;
public void Method()
{
context.WhateverYouWant
}
}