2009-10-12 30 views
7

我們有一項服務來更新客戶信息到服務器。一次服務呼叫需要幾秒鐘,這是正常的。Fire and Forget(Asynch)ASP.NET方法調用

現在我們有了一個新的頁面,可以更新35-50個Costumers信息。改變服務界面以接納所有客戶在這一點上是毫無疑問的。

我需要調用一個方法(比如說「ProcessCustomerInfo」),它將循環客戶信息並調用Web服務35-50次。異步調用服務沒有多大用處。

我需要異步調用「ProcessCustomerInfo」方法。我正在嘗試使用RegisterAsyncTask。網上有各種可用的示例,但問題是在啓動此調用後,如果我離開此頁面,則處理停止。

是否可以實現Fire and Forget方法調用,以便用戶可以在不停止方法處理的情況下從頁面移開(重定向到另一個頁面)?

回答

8

詳情:http://www.codeproject.com/KB/cs/AsyncMethodInvocation.aspx

基本上你可以創建一個指向要異步運行,然後用BeginInvoke來啓動它的方法的委託。

// Declare the delegate - name it whatever you would like 
public delegate void ProcessCustomerInfoDelegate(); 

// Instantiate the delegate and kick it off with BeginInvoke 
ProcessCustomerInfoDelegate d = new ProcessCustomerInfoDelegate(ProcessCustomerInfo); 
simpleDelegate.BeginInvoke(null, null); 

// The method which will run Asynchronously 
void ProcessCustomerInfo() 
{ 
    // this is where you can call your webservice 50 times 
} 
+0

謝謝喬爾!由於MethodInvoker是System.Windows.Form的一部分,我早些時候看到了此方法,但被忽略。它似乎與重定向工作正常,但我需要做更多的測試。但是,我應該使用ASP.NET的這種方法嗎?或者是否有任何Web替代方案? – BinaryHacker 2009-10-12 19:39:12

+0

哎呀,對不起。它可以在ASP.NET中正常工作,但如果您不需要,則必須將System.Windows.Form包含在您的項目中,這將是一個恥辱。相反,您可以創建自己的委託並使用它代替MethodInvoker。我已經更新了上面的代碼示例。 – 2009-10-12 20:02:06

+1

MethodInvoke只是一個已經爲您創建的代理,沒有參數或返回值,因此您不必花時間創建自己的代理。我們剛剛創建的ProcessCustomerInfoDelegate的工作方式完全相同。 – 2009-10-12 20:07:20

0

我認爲問題在於您的web服務期望客戶端返回響應,該服務調用本身不是單向通信。

如果您使用WCF作爲您的Web服務,請撥打http://moustafa-arafa.blogspot.com/2007/08/oneway-operation-in-wcf.html進行單向服務呼叫。

我的兩分錢:海事組織誰把你的構造,你不能改變服務接口添加一個新的服務方法是一個不合理的要求。即使您的服務是公開使用的API,但添加新的服務方法也不應影響任何現有的使用者。

+0

問題沒有得到從服務響應,但呼叫服務50次。單向呼叫服務對我來說無濟於事,我需要找到方法來調用實際進行服務呼叫的方法....... 更改接口是一個問題,因爲此服務由其他供應商公開他們現在不願意改變它。 – BinaryHacker 2009-10-12 19:28:48

+0

單向服務調用可以解決您的問題,您不需要異步觸發它們,因爲它們會打開請求觸發數據並關閉連接,當您點擊提交或任何頁面時,它只是完成一秒鐘就完成了。但是,如果你不擁有這項服務,你不能將其改爲單向。 – 2009-10-13 14:01:32

0

當然你can。在

+0

謝謝。這是我目前正在嘗試的方法。但問題是電影遠離頁面。如果用戶點擊任何鏈接轉到其他頁面,異步處理也會停止。 – BinaryHacker 2009-10-12 19:30:07

+0

@ExpertSoul - 當您更改頁面時,異步處理似乎不太可能停止,因爲根據Restuta鏈接的文檔,異步任務必須在呈現頁面(在將其傳遞到瀏覽器之前)完成之前完成。您是否記得添加帶有Async =「true」屬性的Page指令,或者將頁面的AsyncMode屬性設置爲「true」?有些東西告訴我你的異步任務可能根本就沒有執行。 – 2009-10-12 19:35:12

+0

@ paper1337 - 再次驗證。使用重定向語句時,會調用「OnBegin」方法,但操作會超時而返回到頁面。但OnBegin被處理直到結束。使用重定向語句(我在async方法調用後放置)「OnBegin」永遠不會被調用。另外,雖然在指定屬性Async =「true」的地方提及,但在處理或不處理時我沒有看到任何差異。 – BinaryHacker 2009-10-12 19:49:10

3

這是我剛剛刮起來做到這一點...


    public class DoAsAsync 
    { 
     private Action action; 
     private bool ended; 

     public DoAsAsync(Action action) 
     { 
      this.action = action; 
     } 

     public void Execute() 
     { 
      action.BeginInvoke(new AsyncCallback(End), null); 
     } 

     private void End(IAsyncResult result) 
     { 
      if (ended) 
       return; 

      try 
      { 
       ((Action)((AsyncResult)result).AsyncDelegate).EndInvoke(result); 
      } 
      catch 
      { 
       /* do something */ 
      } 
      finally 
      { 
       ended = true; 
      } 
     } 
    } 

然後

new DoAsAsync(ProcessCustomerInfo).Execute();

還需要設置異步屬性Page指令<%@ Page Async="true" %>

我不確定這是多麼可靠,但它確實爲我所需要的工作。也許一年前寫了這個。

+0

我真的很喜歡這個解決方案。是否有任何更新或新發現的陷阱,因爲您似乎已經使用它一段時間了? – 2011-11-16 14:16:21

+0

我不記得有問題。當這個答案已經在生產中使用時,它仍然存在。 /聳肩 – Dave 2011-11-16 20:24:30