相信許多人都有WCF很難Debug的印象! 的確,Client透過Proxy Class以非同步呼叫執行於Host程序的程式碼,乍看跟呼叫本地元件沒兩樣,但本質上卻涉及一連串複雜機制,要將Server端或傳輸環節中發生的錯誤詳實地傳到呼叫端本來就不是件簡單的事。

昨天剛好遇上一起RIA Service離奇暴斃案,只知WCF呼叫無疾而終,別無線索,最後還是靠著修改程式看結果變化的土方法才找出傳回結果項目過多的問題。不過,在爬文過程中,意外發現了因先前不夠用功所以遺漏的好東西--WCF Tracing

WCF內建了保留追蹤記錄的功能,我們只需在web.config中加入:

<configuration>
   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener"
                   initializeData= "c:\log\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>
</configuration>

就可以將追蹤資料以XML格式寫入Log檔,然後透過Service Trace Viewer Tool檢視WCF運作的細節。以RIA Service暴斃奇案為例:

追蹤資料中明明白白揭示了問題所在:

There was an error while trying to serialize parameter httq://tempuri.org/:GetEntitiesResult. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '.  Please see InnerException for more details.

善用WCF追蹤功能,下回追WCF問題就不用苦無線索想破頭囉! 至於MaxItemsInObjectGraph的問題要如何解決,請收看續集。


Comments

# by Circle

感謝

# by DeanLai

感謝黑大,有方式來查目前公司遇到的問題 不過有發現一個狀況 如果在程式內有寫 try catch,此 log就不會有(在catch中已有處理未預期問題動作),必需沒有寫才有機會可以截到更細部的動作 想請問黑暗大大,如果是以上的方式,有沒有辦法透由 catch 回傳像 ... <ExceptionString>System.NullReferenceException: Object reference not set to an instance of an object. at WaferOUT.Service1.WaferOut(Apply_C oOQA_Data) in D:\QA\WCF\xxx\xxx\Service1.svc.cs:line 35 at SyncInvokeSOM_E_WaferOut(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</ExceptionString> ...等 的錯誤訊息??

# by Jeffrey

to DeanLai,我想到比較簡單的解法是在 try catch 段加個旗標開關,要 Debug 時在 catch 再呼叫 throw 丟出錯誤。

Post a comment