在我的ASP.net MVC应用程序中,我有一个请求,它会执行大量计算以返回结果。这在我自己的服务器上工作正常,但是当我移动到Azure时,连接/请求在4分钟后关闭,所以我没有得到结果我只是得到一个错误。
为了解决这个问题,我计划在一个线程中运行长计算并让客户端轮询以查看它何时完成。
我已尝试过各种方法(线程,线程池,任务和挂起),但我无法将安全上下文/主体/身份从我的请求传递到我的新线程。
这是我正在做的一些sudo代码。 (我意识到多个请求应该有更好的同步,但这是sudo代码)
public static void SlowCalculation(params)
{
_calculationIsRunning = true;
var principal = System.Security.Principal.GenericPrincipal.Current;
if (principal?.IsInRole("MySecurityGroup") ?? false)
{
// lots of long calculations
_resutsAreReady = true;
_calculationIsRunning = true;
}
}
//
// POST: /Get/
public ActionResult GetResults(params)
{
if (_calculationIsRunning)
return View("InProgress");
else if (_resutsAreReady)
return View("Results", results);
else
// start the calcualtion on a new thread to avoiding having very long running connection that azure will close
System.Threading.Tasks.Task.Run(() => SlowCalculation(params));
}
我在SlowCalculation中显示的安全检查在我使用的某些库中实际上已经过时了,所以如果我能帮助它,我真的不想改变它。我只是想从我的请求中获取主体到我的主题。
我已尝试将标识传递给线程函数,但在请求完成时会将其处理掉。
答案 0 :(得分:0)
为什么要尝试检查每个线程中的安全主体。您只需在运行SlowCalculation方法之前检查安全主体。
或者如果你真的想要
public static void SlowCalculation(params, System.Security.Principal.GenericPrincipal principal)
{
_calculationIsRunning = true;
if (principal.IsInRole("MySecurityGroup") ?? false)
{
// lots of long calculations
_resutsAreReady = true;
_calculationIsRunning = true;
}
}
//
// POST: /Get/
public ActionResult GetResults(params)
{
if (_calculationIsRunning)
return View("InProgress");
else if (_resutsAreReady)
return View("Results", results);
else
{
// start the calcualtion on a new thread to avoiding having very long running connection that azure will close
var principal = System.Security.Principal.GenericPrincipal.Current;
System.Threading.Tasks.Task.Run(() => SlowCalculation(params, principal));
}
}
答案 1 :(得分:0)
在ASP.NET进程中长时间运行后台线程并不是一个好主意。解决此问题的正确方法是在Azure服务总线上放置一个计算请求,并通知一些工作进程并运行计算。
您可以在Web应用程序中执行授权检查,并让工作进程在未经授权检查的情况下执行计算。如果计算取决于用户的身份,那么事情会变得更加困难,因为您需要处理会话/令牌过期的可能性。有关如何处理该问题,请参阅my question here。