簡體   English   中英

如何在后台進行任務,等待和異步

[英]How to proceed with Task, await and async in background

我面臨一種需要幫助以了解如何正確進行的情況。

我有一項行動,是一種預算形式。 用戶填寫所有字段后,用戶將按“發送”按鈕保存預算。

發送按鈕將保存數據,然后,將向所有公司發送電子郵件。 當我說所有公司時,我指的是大約1000家公司。

但是,問題在於,當我按下“發送”按鈕時,在為公司發送電子郵件時以及在向所有公司發送電子郵件之后,該頁面均被鎖定,網站將返回視圖。

我想做的是,當用戶按下“發送”按鈕時,網站將節省預算,開始在后台發送電子郵件,並且幾乎立即將視圖返回給用戶,但是與此同時,網站正在發送電子郵件。在后台向1000家公司發送郵件。

我是怎么做到的? 這是我的方法的簽名:

public async Task<PartialViewResult> EnviarProposta(PostOrcamentoServicoProposta proposta)
{
    // persist the budget
    SaveData(proposta);

    // get all companies...
    var companies = getCompanies(proposta);

    foreach (var company in companies)
        await EmailFactory.SendBudget(proposta, company).SendAsync();

    return PartialView(proposta);
}

SendAsync是SMTP的異步方法。

問題是,如何在不等待發送完成的情況下,將發送電子郵件方法簡單地置於后台並返回視圖?

第二個問題是我正在使用一個框架來轉換電子郵件中的視圖,因此,為此,我們需要控制器的上下文。

我應該使用task.factory.startnew嗎?

我應該使用線程嗎?

注意事項:不幸的是,異步控制器操作在這種情況下無濟於事,因為它們在等待異步操作完成時不會對用戶產生響應。 它們僅解決與線程池和應用程序容量有關的內部問題。

由於您是通過asp.net托管的,因此正確的方法有些復雜。

通過線程排隊工作不會通知運行時有工作要做。 這意味着當應用程序域被回收時(無需您的干預就可以不時進行),不能保證您排隊的工作會完成。 如果這與您無關,請繼續執行后台任務。

執行此操作的“正確”方法是以某種方式保留工作(消息隊列,SQL Server等),然后讓另一個主機運行它。

有關更多詳細信息/可能的解決方案,請參見此博客文章

我喜歡排隊需要發送的電子郵件,並讓其他服務實際執行發送的想法...

...特別是因為看起來每封電子郵件都在做一些工作。

例如,您可以在數據庫中創建一個條目,其他服務可從該條目開始工作,並將它們標記為已發送。 如果您的電子郵件內容實際上是通過調用視圖生成的,則單獨的服務仍應能夠通過WebRequest或類似方法簡單地調用相應的Action。

然后,您還可以將工作負載標記為已完成,並有事實證明。

有很多方法可以做到這一點。 例如,您可以簡單地從上面的代碼中刪除await 或者,您可以使用LINQ並讓您的task數組使用延續。

Task[] tasks = companies.Select(c => EmailFactory.SendBudget(proposta).SendAsync(c)).ToArray();
Task.Factory.ContinueWhenAll(tasks, t => { /*do something*/ });

(我假設您需要以某種方式將公司傳遞給每個Send方法調用)

或者,正如艾哈邁德(Ahmed)所述,您可以啟動線程並以這種方式或其他方式發送電子郵件。

如果需要“解雇”方法,請考慮使用Task.Factory.StartNew()。

Task.Factory.StartNew( () => 
{
    foreach(Company c in companies)
    {
        // send your email here, make sure you have good error handling!
        EmailFactory.SendBudget(proposta)
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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