![](/img/trans.png)
[英]TestMethod: async Task TestSth() does not work with .NET 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();
}
基本上,我想調用一個異步方法,該方法在執行數據庫操作的服務中(不同項目)。
我希望異步過程能夠訪問服務方法中的上下文。 這就是為什么我在Task.Factory.StartNew()
使用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
返回void及其非異步方法。 執行上述代碼后,直到完成數據處理后,它才返回控制器。 我認為我在這里缺少什么。 請指導我解決。
謝謝阿莫
您似乎誤解了await
方式。
閱讀此https://msdn.microsoft.com/zh-cn/library/hh191443.aspx#BKMK_WhatHappensUnderstandinganAsyncMethod
設置在任務中運行的內容將使其能夠異步運行,因此您可以在其運行時執行其他操作。
當需要結果繼續時,請使用await
關鍵字。
通過立即創建任務來await
任務,您將立即阻塞直到任務解決。 使其有效地同步。
如果您樂於返回視圖而不等待處理完成,那么我根本就不需要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控制器。
在控制器中時,從控制器中獲取所需的位,並將其傳遞給服務。
我必須從根本上將文件處理的現有功能從同步轉換為異步(這樣,對於大文件用戶,不必等待其他任務)。
那不是async
所做的。 正如我在博客上所描述的, async
不會更改HTTP協議 。
您想要的是ASP.NET上某種形式的“即棄即發”。 我還有一篇博客文章介紹了一些解決方案 。 請注意,使用Task.Factory.StartNew
是所有這些解決方案中最危險的。
最好的(閱讀:最可靠的)解決方案是使用適當的分布式體系結構:ASP.NET應用程序應創建要完成的工作的描述,並將其放置在可靠的隊列中(例如,MSMQ); 然后有一個獨立的后端(例如Win32服務)來處理隊列。 這很復雜,但是比試圖強制ASP.NET進行原本不想做的事情要容易得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.