异步在异步控制器 mvc 4.0 中不起作用
Async does not work in asynchronous controller mvc 4.0
我有一个目标为 targetFramework="4.5" 的 MVC 4.0 应用程序。
我必须基本上将现有的文件处理功能从同步转换为异步(这样对于大文件用户就不必等待其他任务)。
我的密码是
[HttpPost]
public async Task<ActionResult> FileUpload(HttpPostedFileBase fileUpload)
{
Coreservice objVDS = new Coreservice ();
//validate the contents of the file
model =objVDS. ValidateFileContents(fileUpload);
// if file is valid start processing asynchronously
await Task.Factory.StartNew(() => { objVDS.ProcessValidFile(model); }, CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
return view();
}
基本上我想调用一个异步方法,它在执行数据库操作的服务中(不同的项目)。
我希望异步进程能够访问服务方法中的上下文。这就是我使用的原因
TaskScheduler.FromCurrentSynchronizationContext()
在 Task.Factory.StartNew()
.
服务方法如下所示,根据文件类型,调用第二个服务进行数据操作
public async task ProcessValidFile(fileProcessDataModel model)
{
employeeWorkedDataservice service =new employeeWorkedDataservice()
await Task.Factory.StartNew(() =>
{
service .ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source);
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
ProcessEmployeeDataFile
returns void 及其非异步方法。
当执行上面的代码时,它不会 return 到控制器,直到它完成数据处理。我想我在这里遗漏了一些东西。
请指导我解决问题。
谢谢,
阿莫尔
看来您误解了 await
的工作原理。
读这个https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_WhatHappensUnderstandinganAsyncMethod
在任务中设置一些 运行ning 将允许它 运行 异步,所以你可以在它 运行ning 时做其他事情。
当你需要结果继续时,你使用await
关键字。
通过创建任务并立即 await
ing 它,您将立即阻塞直到任务解决;使其有效同步。
如果您愿意 return 无需等待处理完成即可查看您的视图,我认为您根本不需要 await
,因为您根本不想等待对于运算结果。
public task ProcessValidFile(fileProcessDataModel model)
{
employeeWorkedDataservice service =new employeeWorkedDataservice()
return Task.Factory.StartNew(() =>
{
service.ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source);
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase fileUpload)
{
Coreservice objVDS = new Coreservice ();
//validate the contents of the file
model =objVDS. ValidateFileContents(fileUpload);
// if file is valid start processing asynchronously
// This returns a task, but if we're not interested in waiting
// for its results, we can ignore it.
objVDS.ProcessValidFile(model);
return view();
}
关于您的意见:
我会认真考虑 不 将您的控制器传递给您的服务,或者让您的服务依赖于会话和上下文,因为您将业务逻辑与 API控制器。
当你在控制器中时,从控制器中获取你需要的位,并将它们传递给你的服务。
I have to basically convert the existing functionality of file processing from synchronous to asynchronous (so that for large file user don't have to wait for other task).
那不是 async
所做的;正如我在我的博客中所描述的,async
does not change the HTTP protocol.
您想要的是 ASP.NET 上的某种形式的 "fire and forget"。我还有另一个博客 post covers a few solutions。请注意,使用 Task.Factory.StartNew
是所有这些解决方案中最危险的。
最好的(阅读:最可靠的)解决方案是使用适当的分布式架构:您的 ASP.NET 应用程序应该创建对要完成的工作的描述并将其放在可靠的队列中(例如,MSMQ );然后有一个独立的后端(例如 Win32 服务)来处理队列。这很复杂,但比试图强迫 ASP.NET 做一些它从未打算做的事情更不容易出错。
我有一个目标为 targetFramework="4.5" 的 MVC 4.0 应用程序。
我必须基本上将现有的文件处理功能从同步转换为异步(这样对于大文件用户就不必等待其他任务)。
我的密码是
[HttpPost]
public async Task<ActionResult> FileUpload(HttpPostedFileBase fileUpload)
{
Coreservice objVDS = new Coreservice ();
//validate the contents of the file
model =objVDS. ValidateFileContents(fileUpload);
// if file is valid start processing asynchronously
await Task.Factory.StartNew(() => { objVDS.ProcessValidFile(model); }, CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
return view();
}
基本上我想调用一个异步方法,它在执行数据库操作的服务中(不同的项目)。
我希望异步进程能够访问服务方法中的上下文。这就是我使用的原因
TaskScheduler.FromCurrentSynchronizationContext()
在 Task.Factory.StartNew()
.
服务方法如下所示,根据文件类型,调用第二个服务进行数据操作
public async task ProcessValidFile(fileProcessDataModel model)
{
employeeWorkedDataservice service =new employeeWorkedDataservice()
await Task.Factory.StartNew(() =>
{
service .ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source);
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
ProcessEmployeeDataFile
returns void 及其非异步方法。
当执行上面的代码时,它不会 return 到控制器,直到它完成数据处理。我想我在这里遗漏了一些东西。
请指导我解决问题。
谢谢, 阿莫尔
看来您误解了 await
的工作原理。
读这个https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_WhatHappensUnderstandinganAsyncMethod
在任务中设置一些 运行ning 将允许它 运行 异步,所以你可以在它 运行ning 时做其他事情。
当你需要结果继续时,你使用await
关键字。
通过创建任务并立即 await
ing 它,您将立即阻塞直到任务解决;使其有效同步。
如果您愿意 return 无需等待处理完成即可查看您的视图,我认为您根本不需要 await
,因为您根本不想等待对于运算结果。
public task ProcessValidFile(fileProcessDataModel model)
{
employeeWorkedDataservice service =new employeeWorkedDataservice()
return Task.Factory.StartNew(() =>
{
service.ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source);
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase fileUpload)
{
Coreservice objVDS = new Coreservice ();
//validate the contents of the file
model =objVDS. ValidateFileContents(fileUpload);
// if file is valid start processing asynchronously
// This returns a task, but if we're not interested in waiting
// for its results, we can ignore it.
objVDS.ProcessValidFile(model);
return view();
}
关于您的意见:
我会认真考虑 不 将您的控制器传递给您的服务,或者让您的服务依赖于会话和上下文,因为您将业务逻辑与 API控制器。
当你在控制器中时,从控制器中获取你需要的位,并将它们传递给你的服务。
I have to basically convert the existing functionality of file processing from synchronous to asynchronous (so that for large file user don't have to wait for other task).
那不是 async
所做的;正如我在我的博客中所描述的,async
does not change the HTTP protocol.
您想要的是 ASP.NET 上的某种形式的 "fire and forget"。我还有另一个博客 post covers a few solutions。请注意,使用 Task.Factory.StartNew
是所有这些解决方案中最危险的。
最好的(阅读:最可靠的)解决方案是使用适当的分布式架构:您的 ASP.NET 应用程序应该创建对要完成的工作的描述并将其放在可靠的队列中(例如,MSMQ );然后有一个独立的后端(例如 Win32 服务)来处理队列。这很复杂,但比试图强迫 ASP.NET 做一些它从未打算做的事情更不容易出错。