2013-12-16 29 views
1

我對Web API非常陌生,並且我需要實現一個不尋常的模式。在我的控制器的Post方法中,它需要一個包含CallbackURL的對象。它會立即返回一個HTTP響應給調用者。之後,它將使用第三方的場外API對該對象執行一些工作。完成該工作後,控制器將該工作的結果發佈到CallbackURL。來自web api控制器的異步回調

但是,我不知道如何在Web API中實現這一點。一旦我返回HTTP響應,控制器的生命週期結束了,是正確的?如果是這樣,在我返回響應後,如何執行我需要做的工作?

回答

2

如果您只需要發佈結果的網址,而不是發起呼叫的客戶端,你可能做的一樣簡單的東西是這樣的:

public string MyAPIMethod(object input) 
{ 
    Task.Factory.StartNew(() => 
    {   
     //call third-party service and post result to callback url here.   

    }); 

    return "Success!"; 
} 

API調用將立即返回,並您創建的任務將繼續在另一個線程中處理。

+0

非常感謝。我相信這是我所需要的。但是,在實現它之後,我會在多個請求同時發生時注意到崩潰。崩潰問題看起來幾乎是隨機的:不應該爲null的各種對象都爲null,並且它永遠不會是同一個對象。你碰巧知道爲什麼開始這樣的任務會造成這種情況? 或者,讓我問一下,如果這個方法可以安全地用於可能被大量同時請求觸發的API, –

+0

這取決於任務中的代碼是否是線程安全的。所有的多線程陷阱都需要避免。特別要考慮的一件事是,你將無法訪問任務線程中的HttpContext。 –

2

這假設您想要將第三方查詢的結果返回給調用者。

你是對的,這超出了WebAPI的可能範圍。一旦你返回HTTP響應,客戶端也沒有連接到你的服務器。

你應該看看Asp.Net SignalR,它允許客戶端和服務器之間的連接,在現代瀏覽器中工作,甚至回到IE7(儘管官方不支持),並支持非瀏覽器客戶端。

然後你可以做幾件事情,所有這些都需要客戶端先連接到SignalR。

選項1:您可以調用您的WebApi控制器,它可以返回,但不會在啓動任務之前調用。這個任務可以查詢第三方API,然後通過SignalR調用你想提供的結果的函數。

選項2:您可以調用SignalR Hub操作,該操作可以與您的客戶進行對話。您可以告訴客戶立即迴應,查詢第三方API,然後返回您想要提供的結果。

2

創建完成請求的任務(如上面的Jason P建議的)很可能會解決問題,提供線程安全性。但是,如果對第三方API的調用需要花費大量時間才能完成,並且/或者您期望有許多併發客戶端,那麼這種方法可能會損害Web服務的性能。如果是這樣的話,您的問題似乎是稱爲「請求/確認/回叫」(也稱爲「請求/確認/中繼」)的服務模式的完美候選人。使用該模式,您的Web API方法將僅將每個請求(包括回調URL)存儲到隊列/數據庫中並快速返回。一個單獨的模塊(可能運行在多臺計算機上,具體取決於任務的數量和複雜性)將負責完成任務,並隨後通過回調URL通知完成(請參閱http://servicedesignpatterns.com/ClientServiceInteractions/RequestAcknowledge)。