2012-05-29 76 views
3

我正在將桌面應用程序(WinForm)移植到Web應用程序(Java/Spring/JPA)。問題很多,我正在努力...Web應用程序和多線程

現在的問題是線程!

在原始應用程序中,執行從數據庫中導出某些數據的過程,有一個進度條指示進程的進度。

我想在新的web應用程序中移植此進度條。爲此,我想使用AJAX並使用單獨的線程來運行數據導出。

的主要問題是:

  • 我是否遵循正確的方法?在Web應用程序中使用多線程有問題嗎?
  • 如果在導出過程中F5或刷新按鈕被按下,究竟發生了什麼?我怎樣才能停止這個過程?
  • 如何定期更新進度欄?我必須通過ajax向服務器撥打電話嗎?
+0

你看過[這裏](http://forum.springsource.org/showthread.php?26661-quot-progress-bar-quot-in-Spring-web-app)並試過解決方案嗎? –

+0

@LuiggiMendoza還沒...我來看看。謝謝。 – davioooh

回答

0

找到我的答案內嵌

我下面的正確方法?在web應用程序中使用多線程有問題嗎?

- 是你在正確的道路上。不,在web應用程序中的多線程中沒有這樣的問題,並且像在WinForm中一樣簡單。而不是使用分派器來更新用戶界面,你將會進行AJAX調用,並且會發生javascript DOM操作。

如果在導出過程中F5或刷新按鈕被按下,究竟發生了什麼?我如何阻止這個過程?

- 不幸的是沒有簡單的方法。標準的方式是,當這種處理完成並且用戶點擊F5時,您將顯示一個對話框(藉助javascript)並通知用戶該作業仍在運行。如果用戶仍然想刷新,那麼你已經向服務器發出了另一個取消任務的請求(你需要存儲線程ID或取消標記以取消任務)

如何更新進度條定期?我必須通過ajax向服務器撥打電話嗎?

- 標準的方式是,一般你顯示一個加載圖像。如果你想顯示一個上下文敏感的進度條,這意味着你必須進行輪詢。這是Dino Espito的一個例子。雖然它在ASP.NET中,但您可以理解其基本原理 Dino Espito

+0

當你說_「你會顯示一個對話框(在javascript的幫助下)並通知用戶該作業仍在運行」_,你的意思是攔截「刷新事件」? – davioooh

+0

是的,您可以通過處理javascript中的按鍵事件輕鬆完成此操作。 – Anand

1

我主要是一個ASP.Net開發人員,但從我所瞭解的HTTP協議來看,這不是解決問題的方法。我已經看到了很多相當聰明的解決方案,但最終變得清楚的是,HTTP協議根本不是這樣設計的。

很明顯,你知道一個flash或silverlight應用程序可以做到這一點,但它有它自己的一套問題。

我自己我更喜歡保持服務器上的所有奇怪。在過去,我不得不想出一種方式來通過網絡應用程序發送數千封電子郵件,並更新用戶的來訪方式。我設計了一組表作爲隊列。 Web應用程序只需在該隊列中放置任何傳遞請求,並且進度條將由檢查隊列中項目狀態的請求確定。在後臺運行的是一個windows服務,它也會檢查這個隊列,並且實際上負責發送郵件並設置每個項目完成或失敗時的狀態。

開發起來有點困難,因爲Windows服務可能會非常棘手,但一旦啓動並運行,它就非常流暢和可靠。根據您的情況,也許一個簡單的計劃任務設置爲每隔幾分鐘運行一次就可以爲您解決問題。

+0

所以,糾正我,如果我錯了,我可以啓動一個線程,做「髒工作」,然後從我的網頁,我可以做出定時請求,以確定進程的進程... – davioooh

+1

我不知道你使用的是什麼樣的web服務器,但是在web應用程序中產生線程總是讓我感到不舒服。在IIS中,如果在生成的線程中拋出未捕獲的異常,它可能會導致整個Web服務器崩潰。我不確定這是否適用於Apache。 –

+0

謝謝你的建議 – davioooh

1

我不一定會直接跳到明確爲導出運行單獨的線程。雖然這樣做是理想的,但Web容器做這件事的能力將成爲一個限制因素。您的傳統Java EE應用服務器通常不鼓勵爲此產生線程(儘管您可以連接到此線程池)。有些容器在阻塞線程時非常好,直到完成工作(例如使用Jetty和Camel的Karaf),以便在導出過程中可以處理其他Web請求。但我的猜測是,你可能在「開始導出」線程阻塞之前就可以了,直到它收到響應。

此導出需要多長時間?幾秒鐘,還是我們在這裏談話更近?如果它更短,我會認爲只需在它上面放一個小的「等待」圖標(使用您最喜歡的Ajax庫,無論這是什麼)就足夠了。

如果你真的想要一個真正的狀態欄來定期刷新自己,那麼你必須在某個頻率上進行輪詢。據推測,這可能是一個簡單的請求,它會爲該作業ID的數據庫表中的作業加載某種進度。

+0

該過程可能需要幾分鐘時間,所以我認爲阻止等待響應的主線程可能不是正確的方法。我可以通過異步請求啓動進程並定期檢查導出進程的進度...... – davioooh

+0

即使您從瀏覽器的角度發出異步請求,服務於該請求的服務器上的線程也將在後臺被阻止。在這種情況下,它將無法處理其他HTTP請求。如果你可以這樣做,這是最簡單的方法,但是如果你想釋放它,那麼你應該涉及一個線程池,並通過Executor委託給一個Runnable。 –

+0

+1謝謝你的建議 – davioooh