[C#]設定動態叫用Web Service 的 Time out 時間

  • 20668
  • 0
  • C#
  • 2010-12-15

[C#]設定動態叫用Web Service 的 Time out 時間

前陣子公司某套使用 VB 6 開發的老系統(A系統)在串另一套由Java開發的Web Service(B系統)取得資料時出了一些問題,A系統是用微軟的SOAP Toolkit 3.0去呼叫Web Service,某二天A系統在呼叫B系統時,突然會不定時出現「5415 Connector: Connection time out」的錯誤(SOAP Toolkit的time out 時間設30秒)。該期間二套系統並沒有進行任何程式異動,但Server Team表示Server無異常,Network Team也表示網路正常,在無法查明原因的情況下,問題竟又被界定成是AP系統的問題,所以SD Team就又被犧牲當砲灰,被要求自已想辦法解決此問題,妙的是那二天過後,二套系統的串接又正常了。

雖然系統正常了,但SD Team還是要提出對策,在原因不明的情況下,有人就提出懷疑 SOAP Toolkit 是過時的工具,問題可能是它,要求A系統不要使用SOAP Toolkit去呼叫B系統。對於此論點本人不予置評,但既然有人要求了,自已也不想花太多的時間去爭論,那就動手吧!

於是著手規畫使用.Net開發一個COM+元件,讓A系統透過該COM+元件去呼叫B系統的Web Service。在規畫的過程中,突然想起之前曾看過gipi兄寫過 動態叫用Web Service 一文,可避開一般常見的發行佈署時引用Web Service參考的問題。

於是參考該文內容,自行改寫符合所需的COM+元件,但又延伸出另一個問題,依經驗前端網頁回應時間若超過8秒,公司內部某些使用者就會開始叫,那使用動態叫用Web Service 要如何設定其Time out 的時間?   在請教過gipi兄及拜過google大神之後,找到了用 PropertyInfo.SetValue 方法來設定Time out。

SetValue

動態叫用Web Service 一文的Sample為例,只要在最後的 InvokeMethod.Invoke()前加入PropertyInfo那二行語法即可完成Time Out時間=30000毫秒=30秒的設定。( SetValue的第二個參數30000可改用變數去控制Time Out的時間)

	//若沒有overload的話,第二個參數便不需要,這邊要注意的是WsiProfiles.BasicProfile1_1本身不支援Web Service overload,因此需要改成不遵守WsiProfiles.BasicProfile1_1協議 
            MethodInfo tInvokeMethod = tType.GetMethod(pMethodname, tArgsType);

            //設定 TimeOut 時間,單位為 millisecond (ms)
            PropertyInfo propInfo = tTypeInstance.GetType().GetProperty("Timeout");
            propInfo.SetValue(tTypeInstance, 30000, null);

            //實際invoke該method 
            objRtn = tInvokeMethod.Invoke(tTypeInstance, pArgs);

 

最後進行簡單的測試以驗証Time Out設定是否有效。

 

先將寫好的COM+註冊到【元件服務】(註冊方式請參考Topcat兄的 N-Tiers開發方式(COM+元件的註冊、修改) 一文)。

然後準備一個簡單的Web Service來測試,其中Hello這個Method會在經過 SleepTime 的時間(毫秒)之後回傳 SomeWords字串值。

Web Service程式碼如下:

	namespace SOAPWebService
{

    [WebService(Namespace = "SOAPWebService")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class SOAPWS : System.Web.Services.WebService
    {

        [WebMethod]
        public string Hello(string SomeWords, int SleepTime)
        {
            System.Threading.Thread.Sleep(SleepTime);
            return SomeWords;
        }    
    }
}

另外寫支小程式來試一下Time Out設定是否真的可行。

設定Web Service的SomeWords=''HeloWorld!",SleepTime=2秒,而呼叫Web Service之COM+設定TimeOut=3秒,執行結果可正常取回''Hello Word!'',執行總時間為2.527秒。(其中2秒是Web Service的Sleep Time,而0.527秒則為編譯動態WebService的時間)

執行畫面如下:

'SOAP1

 

若將SleepTime設為4秒,TimeOut維持3秒不變,執行後就會產生「The operation has timed out」的錯誤訊息,執行時間為3.638秒。(其中0.638為編譯時間,另3秒則是設定的Time Out時間)

執行畫面如下:

SOAP2

 

參考資料:

Koders Code Search: DynamicWebServiceProxy.cs - C#