2013-07-22 24 views
0

我目前正在運行一個電子商務網站。多線程或異步在網站中的冗長任務

因此,當用戶籤,我有一個銀行回調網頁...

但因爲我有發生後付款(目前同步完成)執行冗長的任務,用戶必須等待很長一段時間纔將其重定向回我的網站。

我試圖做一個與thread.start後臺線程,但問題是,我鬆了會議,這是不明顯的。

因此,根據這個描述,你將如何進行?你會去異步或多線程?

如果你去異步,它會是怎樣的?

所以我們有類似:

public ActionResult CallBack() 
{ 
    if (AcceptPayment() == "OK") 
    { 
     LenghtyTask(); 
    } 

    return RedirectToUrl("MyWebSite"); 
} 
+0

您是否在嘗試修復用戶需要等待很長時間的事實,或者您是否試圖讓這個冗長的進程停止對目前的整體可擴展性造成影響? –

+0

你的實際問題是,它聽起來像你想要客戶端更新與一些用戶界面,而冗長的任務正在運行,是嗎?如果是這樣,那麼這個問題或多或少沒有意義,因爲您需要創建一個ajax請求端點來確定長時間運行的任務的狀態。 – Tejs

+0

異步實際上是啓動一個線程,但是您只是釋放服務器資源,而不是真的讓用戶更快。 – Robert

回答

3

首先,在ASP.NET站點上運行的後臺線程是一個很大的禁忌,因爲你必須在應用程序生命週期的控制。應用程序池可以被關閉或回收,這意味着你的數據丟失。

您可以使用數據庫來存儲任務(並根據工作進度更新其狀態),或者簡單地創建一個Windows服務或類似的執行作業。


當你有在工作運行任何控制,這是毫無意義的,詢問是否應該使用異步或線程既不他們將釋放所有資源(即讓應用程序運行得更快)。

只需選擇一個您知道的並完成HTTP請求。告訴用戶該作業正在後臺處理,並讓他刷新瀏覽器以查看其進展情況。另一種方法是使用Ajax或ASP.NET SignalR來檢查後臺進度。

+1

我同意100%。 如果你想讓你的解決方案很好地擴展,那麼考慮一下服務總線,或者更簡單的一個pub/sub機制,讓另一個進程(windows服務也許)知道在後臺需要完成的工作。 –

0

可能會去像這樣

public ActionResult CallBack() 
{ 
    if (AcceptPayment() == "OK") 
    { 
     // simply launches the task and moves on 
     Task.Run(LenghtyTask()); 
    } 

    return RedirectToUrl("MyWebSite"); 
} 

現在你頁面上:RedirectToUrl(「MyWebSite」)

你是要去必須建立像TEJS一個Ajax請求指出的,可以通知用戶在任務實際開展AJAX ..in情況下,前完成

public ActionResult IsTaskFinished() 
{ 
    // No clue where your transaction is, but your gonna need to know it to check it's state 
    return JSON(SomeClass.Current.IsTaskFinished(ContextBoundObject.Transaction.Id)); 
} 

你可能會想呼叫SomeClass.Current.IsTaskFinished(ContextBoundObject.Transaction.Id)上/ MyWebSite轉換已經完成。

function isTaskFinished() { 
    $.post("/IsTaskFinished").always(function(data) { 
     if (!!data) { 
      setTimout(isTaskFinished, 3000); 
     } 
     else { 
      // yay i'm done, inform user ! 
     } 
    }); 
} 

當然,你必須在重試次數限制,錯誤處理等

+1

任務與使用線程池時的背景線程有相同的問題。在這裏閱讀更多:http://stackoverflow.com/questions/16254567/asp-net-long-running-task-thread-is-being-aborted-exception – jgauffin

+0

不說等待..我同意數據庫/隊列。但你必須以某種方式推動它。 LenghtyTask()可能是實際的任務,或者只是推向數據庫,取決於他想要實現的安全性。 – Robert

-1

到因子I將在隊列(MSMQ,RabbitMQ的,等等)粘在冗長的操作,並有工作進程(ES) (最好是一個Windows服務器)使作業離隊並執行那些冗長的操作。

關於如何通知用戶,有幾個選項,但我的選擇是實時更新,您可以通過您的服務器推送到您的客戶端瀏覽器。只需在您的應用程序上安裝SignalR端點並通過SignalR連接即可。NET客戶端在您的工作進程(es)上。一旦完成冗長的操作,就可以通過SignalR端點通知連接的客戶端。

無論你做什麼,避免在ASP.NET下對任何數據關鍵操作進行後臺操作,恕我直言,@ jgauffin指出。原因如下:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx