2011-07-14 54 views
1

我正在研究與Web服務通信的應用程序。客戶端應用程序(silverlight-4.0)將調用Web服務並觸發長時間運行的任務。由於任務完成需要一些時間,因此它將在單獨的線程中執行。 (使用System.Threading.Tasks.Task.Factory.StartNew()創建單獨的任務。)啓動任務後,服務調用將返回一個ID並完成連接。
這個ID應該是我需要識別的任務,所以我可以與它溝通。如何與後臺任務進行通信?

可能使用另一個連接進行下一次調用,檢查是否已完成任務。爲此,該ID是呼叫的一部分。在服務器上,現在需要檢查任務是否仍在運行或者是否已完成。我如何再次找到這個任務?


該服務在Azure上運行,並且由於負載平衡,第二個調用可能位於完全不同的系統上。在我看來,這是不可能完成的,但是再次...
這個Q與this Q有關。

回答

3

這樣做的正確方法是使用基於隊列的通信。原因是可擴展性。你想讓你的服務的「實例」接收請求,並且你希望「一個實例」將結果返回給客戶端嗎?

您可以快速瀏覽一下我的關於AppFabric Queues的博客文章,但它們太笨重了。下面是如何I'do它:

創建WorkerRequest類,看起來像這樣

public class WorkerRequest { 
    string clientId; 
    MyTaskEnum taskToPerform; 
} 

寫入隊列存儲,(在我的生產代碼,我使用的是我還沒有博客的包裝關於然而,但計劃:)),添加請求。

有一個工作線程監聽這個隊列,並且當收到一個請求時,產生一個新的線程來完成它。完成後,使用您的任務&客戶端ID作爲您的密鑰,寫入表存儲。這樣,你可以隨時檢查狀態(簡單/ GET /請求表)+你已經解除了&可擴展性已經解決。

希望它有幫助。

UPDATE:想解釋一點,所以我決定更新帖子=)

您可以在「Web角色」,這是我會做什麼創建一個WCF Web服務。我前一段時間是blogged about。在同一個角色中,您創建一個工作人員。你通過實施RoleEntryPoint的課程來達到這個目的。這個類(位於Microsoft.WindowsAzure.ServiceRuntime)的樣子:

public abstract class RoleEntryPoint 
    { 
    public virtual bool OnStart() 
    { 
     return true; 
    } 

    public virtual void Run() 
    { 
     Thread.Sleep(-1); 
    } 

    public virtual void OnStop() 
    { 
    } 
    } 

您簡單地實現在運行一段時間(true)循環,詢問隊列是否有用於處理任何新的消息。當收到這樣的消息不會產生一個新的,只是處理它。如果您想縮放它,可以通過添加新實例進行縮放。顯然,這可能是昂貴的,所以實際上產生新線程是明智的,但僅限於某個極限,例如,最多5個線程。如果池中沒有線程,則將消息返回隊列(當您完成消息時,您需要調用Complete(),否則它不一定會被刪除)。它會在稍後或另一名工作人員中被拾起。

因此,當工作線程完成時,將結果寫入表存儲並完成。

4

讓任務在表存儲/ appfabric緩存中報告其狀態。然後,當nsomeone輪詢狀態時,只需從所使用的持久性機制中讀取任務ID X的相應狀態即可。

+0

+1兩個答案 - 同一個想法在同一時間。在極端情況下 - 客戶端和服務器之間需要真正緊密的耦合 - 那麼您也可以使用粘滯會話模式 - http://dunnry.com/blog/2010/10/14/StickyHTTPSessionRoutingInWindowsAzure.aspx - 但這不適用於簡單情況下(IMO) – Stuart

+0

我必須誠實地說,馬丁巴比我快了4秒。 –

+0

表存儲/ appfabric緩存的使用是誘人的,並會簡化大部分的輪詢。但大衛斯蒂爾建議的工作者角色聽起來也很有趣... –

2

該任務只需要在某處完成並保存結果,如果結果是預期的。

您可以在任何可用的位置存儲帶有任務ID的完成和表存儲或SQL Azure。後續輪詢以查看它是否完成可以檢查該存儲並返回它是否完成。

解決此問題的另一種方法是讓長時間運行的任務在輔助角色中運行。如果這個工作者角色暴露了一個內部端點,那麼任何一個Web角色都可以詢問工作者角色是否完成。

+0

工人角色?嗯...有趣的概念。沒有想過這些。 –

+0

如果任務長時間運行,但不是太CPU或IO密集,那麼你可以在你的web角色的單獨線程中運行它們並節省資金。如果他們是勤奮的工作,那麼最好將他們推到一個單獨的工作者角色中,以免對您的網絡角色產生不利影響。 –

相關問題