簡體   English   中英

異步在異步控制器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();


}

基本上,我想調用一個異步方法,該方法在執行數據庫操作的服務中(不同項目)。

我希望異步過程能夠訪問服務方法中的上下文。 這就是為什么我在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM