[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。
以 動態叫用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的時間)
執行畫面如下:
若將SleepTime設為4秒,TimeOut維持3秒不變,執行後就會產生「The operation has timed out」的錯誤訊息,執行時間為3.638秒。(其中0.638為編譯時間,另3秒則是設定的Time Out時間)
執行畫面如下:
參考資料: