2012-02-08 14 views
2

對不起,如果這是一個相當長的問題,我需要一些關於人們認爲是最好的方法(因爲有一些)的建議。在.Net中的後臺處理 - 需要建議

此刻,我的項目有一個方法

do_job(jobid,userid) 

這種方法需要一兩分鐘,然後重定向到另一個頁面。

這已被重寫,以便它現在在後臺運行並重定向到另一個頁面,同時繼續do_job的線程。 - 這工作正常。

在一個Default.aspx頁面,一個button_click事件:

Dim d as New do_job_delegate(AddressOf do_job) 
d.BeginInvoke(jobid,userid, New AsyncCallback(AddressOf Callback),d) 
Response.redirect("results.aspx") 

內容涉及

Delegate Sub do_job_delegate(Byval jobid as integer, Byval userid as integer) 

Public Sub do_job(Byval jobid as integer, Byval userid as integer) 
    ' Do something for several seconds 
End Sub 

Public Sub Callback(Byval ar As IAsyncResult) 
    ar.AsyncState.EndInvoke(ar) 
End Sub 

這基本上我想要做什麼,用戶可以繼續在網站上做的事情, do_job方法在後臺運行併成功完成其任務。

但是,我現在添加了這個do_job方法,並且有幾個小任務,每個在do_job中花費30秒左右的時間,並且他們可以/應該並行運行。 如

Public Sub do_job(Byval jobid as integer, Byval userid as integer) 
    loop through between 1 or more (up to roughly 10 items) 
     'process that takes about 30 seconds 
    end loop 
End Sub 

所以我希望發生的是什麼 - 30秒就業x個=時間花費在 - 這do_job需要的是時間最長的工作時間最長(30秒),而不是最長的時間此時此刻。

由於我已經在使用委託從UI分離進程,任何人都可以提供任何建議/最佳做法,我應該如何重新安排我的do_job方法,以便它可以處理併發任務以進一步提高總體速度。

謝謝!

回答

4

我建議您在花費大量時間之前,考慮將工作移至單獨的服務,而不是在您的Web服務器上以內聯方式運行。

只要將一條記錄放入一個數據庫表並讓該服務監視它即可。

這是Phil Haack的一篇文章,解釋了爲什麼你不應該混淆Web服務器上的線程。

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

至於並行執行的任務,看看.NET 4.0並行庫。他們讓這種事情變得非常簡單。

http://msdn.microsoft.com/en-us/library/dd460717.aspx

+0

感謝您的快速回復,不幸的是我被困在這個當前工作的asp 2.0上。 – norbert 2012-02-08 15:23:17

+0

@AndyGreen然後去服務。 .NET的一個好處是你可以使用你已經熟悉的語言等來構建它。 – 2012-02-08 15:27:25

+0

如果您的組織允許,您可以始終使用.net 4服務,同時將網絡保留爲2.0。如果你的組織不允許,找一份新工作。 :) – BNL 2012-02-08 15:28:07

1

正如@BNL說,這確實應該在存在的web請求/響應管道之外的服務或其它過程中完成的。你目前的方法可能會造成一些問題,如果你獲得了大量的流量,你將會產生比你的系統合理處理更多的線程。這消除了您在單用戶環境中從多線程獲得的任何好處,事實上,它可能會增加很多開銷,導致響應速度比單線程方法慢。

考慮將已經在數據庫表中要完成的任務的描述:

id 
job_id 
user_id 
date_created 
date_started 
date_completed 
status_code 

,並讓您的服務調查該表找到了需要處理的工作。這爲您提供了許多額外的好處,包括生成成功/失敗報告的能力,跨IIS復位持續存在的工作排隊等。如果Web應用程序需要在作業完成時提醒用戶,請檢查頁面加載表(簡單)或定期通過AJAX請求(不太容易),就像StackOverflow在檢查您正在閱讀的問題的新回覆時所做的那樣。

See this article for an overview of creating services in VB.NET.

做不到這一點,一個簡單的方法,推出了大量的並行相似的任務是通過Parallel.ForParallel.ForEach,但我不能強調不夠多麼危險,這是在網絡或其他多用戶環境。

此外,你應該在ASP.NET版本.NET framework版本區分。許多/大多數服務器應具有.NET Framework 4的使用,即使他們的網站都在使用ASP.NET 2

See this MSDN article for an example of the latter,但服務確實是要走的路。