ReadOnly Session 加上异步操作和任务线程。控制器如何表现呢?
ReadOnly Session coupled with Asynchronous Action and Task Thread. How does the Controller behave then?
在 Asp.Net MVC 应用程序中,如果异步控制器的 Session 行为是只读的,则其 Action 方法也是异步的,并且在其中我们创建了一个任务线程来执行一些长 运行 的事情,例如:
[SessionState(SessionStateBehavior.ReadOnly)]
public class UploadController : AsyncController
{
public void UploadFilesAsync(IEnumerable<HttpPostedFileBase> assetFiles,
string filesMetaInfo)
{
var postedFiles = assetFiles;
var fInfo = filesMetaInfo;
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(
() => ProcessUploadedFile(postedFiles, fInfo),
CancellationToken.None, TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
public ActionResult UploadFilesCompleted(object result)
{
return Json(new
{
status = "OK"
}, "text/plain");
}
private void ProcessUploadedFile(IEnumerable<HttpPostedFileBase>
assetFiles, string filesInfo)
{
// Do some long running stuff here like file processing.
// ......................
// ..................................
AsyncManager.Parameters["result"] = "success"
AsyncManager.OutstandingOperations.Decrement();
}
}
现在有两个问题:
这个控制器操作方法 UploadFilesAsync() 是否会在内部任务线程工作完全完成后为其他请求释放此控制器,或者在任务刚刚开始执行后立即对其他请求可用?
另外,如果我通过在其上应用 "Synchronized" 属性使此 UploadFilesAsync() 方法以同步方式运行,会发生什么情况?示例:
[MethodImpl(MethodImplOptions.Synchronized)]
Will this Controller Action method UploadFilesAsync(), release this
Controller for other Requests once the inside Task thread work
completes fully or be available to other Requests right after when the
Task just starts executing?
"release this controller" 我假设您的意思是释放当前占用的 ASP.NET 线程池线程来处理您的消息。如果是这样,答案是后者。它会立即释放当前线程,而不会等待执行的内部任务完成。
Also what will happen if I make this UploadFilesAsync() method behave
in a synchronous manner by applying "Synchronized" attribute on it?
MethodImplOptions.Synchronized
不会使方法 运行 同步。它就像用 lock (this)
包装你执行的整个方法。这意味着多个调用者将无法使用您的 Controller
的同一个实例,但无论如何都不会发生,因为每个请求都会启动一个新的 Controller
。这意味着它没有任何区别。
作为旁注 - You should not be using Task.Factory.StartNew
nor Task.Run
inside ASP.NET, because any work offloaded to that threadpool thread will not be registered with IIS, which means your thread could be abnormally aborted due to IIS recycling. Instead, look into HostingEnvironment.QueueBackgroundWorkItem
if you're using .NET 4.5.2, or look into Stephan Clearys AspNetBackgroundTasks
在 Asp.Net MVC 应用程序中,如果异步控制器的 Session 行为是只读的,则其 Action 方法也是异步的,并且在其中我们创建了一个任务线程来执行一些长 运行 的事情,例如:
[SessionState(SessionStateBehavior.ReadOnly)]
public class UploadController : AsyncController
{
public void UploadFilesAsync(IEnumerable<HttpPostedFileBase> assetFiles,
string filesMetaInfo)
{
var postedFiles = assetFiles;
var fInfo = filesMetaInfo;
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(
() => ProcessUploadedFile(postedFiles, fInfo),
CancellationToken.None, TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
public ActionResult UploadFilesCompleted(object result)
{
return Json(new
{
status = "OK"
}, "text/plain");
}
private void ProcessUploadedFile(IEnumerable<HttpPostedFileBase>
assetFiles, string filesInfo)
{
// Do some long running stuff here like file processing.
// ......................
// ..................................
AsyncManager.Parameters["result"] = "success"
AsyncManager.OutstandingOperations.Decrement();
}
}
现在有两个问题:
这个控制器操作方法 UploadFilesAsync() 是否会在内部任务线程工作完全完成后为其他请求释放此控制器,或者在任务刚刚开始执行后立即对其他请求可用?
另外,如果我通过在其上应用 "Synchronized" 属性使此 UploadFilesAsync() 方法以同步方式运行,会发生什么情况?示例:
[MethodImpl(MethodImplOptions.Synchronized)]
Will this Controller Action method UploadFilesAsync(), release this Controller for other Requests once the inside Task thread work completes fully or be available to other Requests right after when the Task just starts executing?
"release this controller" 我假设您的意思是释放当前占用的 ASP.NET 线程池线程来处理您的消息。如果是这样,答案是后者。它会立即释放当前线程,而不会等待执行的内部任务完成。
Also what will happen if I make this UploadFilesAsync() method behave in a synchronous manner by applying "Synchronized" attribute on it?
MethodImplOptions.Synchronized
不会使方法 运行 同步。它就像用 lock (this)
包装你执行的整个方法。这意味着多个调用者将无法使用您的 Controller
的同一个实例,但无论如何都不会发生,因为每个请求都会启动一个新的 Controller
。这意味着它没有任何区别。
作为旁注 - You should not be using Task.Factory.StartNew
nor Task.Run
inside ASP.NET, because any work offloaded to that threadpool thread will not be registered with IIS, which means your thread could be abnormally aborted due to IIS recycling. Instead, look into HostingEnvironment.QueueBackgroundWorkItem
if you're using .NET 4.5.2, or look into Stephan Clearys AspNetBackgroundTasks