0

我有一个间歇性失败的 WCF 服务。当它失败时,我可以从 svctraceviewer 信息中看到两个单独的线程同时请求“连接信息”。一个线程成功,另一个线程失败并出现以下错误:“使用 WebContentTypeMapper 时遇到意外异常。” 这些请求是相同的,除了 POST 正文中的一些值,所以我认为真正的问题与请求“连接信息”时的冲突有关。在此“连接信息”请求期间,我无法找到有关 WCF 运行时正在做什么的任何信息。

我应该注意到客户端发布未编码的 XML 并使用 application/xml 的 HTTP Content-Type 标头,因此我有一个自定义绑定来接受 xml 流。我无法更改客户端发布到我的服务的方式。

想法?

网络配置

<system.serviceModel>
    <services>
        <service name="SAPCallbackHandlerNamespace.SAPCallbackHandler" behaviorConfiguration="">
            <endpoint address="" binding="customBinding" contract="SAPCallbackHandlerNamespace.ISAPCallbackHandler" behaviorConfiguration="webBehavior" bindingConfiguration="customBindingHTTP" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost/service.svc/" />
                </baseAddresses>
            </host>
        </service>
    </services>
    <bindings>
        <customBinding>
            <binding name="customBindingHTTP">
                <webMessageEncoding webContentTypeMapperType="SAPCallbackHandlerNamespace.RawContentTypeMapper, SAPCallbackHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                <httpTransport manualAddressing="true" maxReceivedMessageSize="524288000" transferMode="Streamed" />
            </binding>
        </customBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="webBehavior">
                <webHttp/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
</system.serviceModel>

代码

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
[DataContract]
public class SAPCallbackHandler : ISAPCallbackHandler
{
    public string ParseIncomingXML(Stream incomingXML)
    {
        ...
    }
}

public class RawContentTypeMapper : WebContentTypeMapper
{
    public override WebContentFormat GetMessageFormatForContentType(string contentType)
    {
        if (contentType.Contains("text/xml") || contentType.Contains("application/xml"))
        {
            return WebContentFormat.Raw;
        }
        else
        {
            return WebContentFormat.Default;
        }
    }
}

界面

[ServiceContract]
public interface ISAPCallbackHandler
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    string ParseIncomingXML(Stream incomingXML);
}

“连接信息”跟踪:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
        <EventID>262168</EventID>
        <Type>3</Type>
        <SubType Name="Information">0</SubType>
        <Level>8</Level>
        <TimeCreated SystemTime="2013-11-04T16:52:26.3746976Z" />
        <Source Name="System.ServiceModel" />
        <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
        <Execution ProcessName="w3wp" ProcessID="3992" ThreadID="7" />
        <Channel />
        <Computer>TX-APP-J01</Computer>
    </System>
    <ApplicationData>
        <TraceData>
            <DataItem>
                <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Information">
                    <TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Channels.ConnectToIPEndpoint.aspx</TraceIdentifier>
                    <Description>Connection information.</Description>
                    <AppDomain>/LM/W3SVC/2/ROOT-1-130280558217413872</AppDomain>
                    <Source>System.ServiceModel.Activation.HostedHttpTransportManager/4720237</Source>
                    <ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/DictionaryTraceRecord">
                        <LocalEndpoint>10.198.147.12:80</LocalEndpoint>
                        <RemoteEndpoint>163.231.6.69:24074</RemoteEndpoint>
                    </ExtendedData>
                </TraceRecord>
            </DataItem>
        </TraceData>
    </ApplicationData>
</E2ETraceEvent>

错误跟踪:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
        <EventID>131075</EventID>
        <Type>3</Type>
        <SubType Name="Error">0</SubType>
        <Level>2</Level>
        <TimeCreated SystemTime="2013-11-04T16:52:26.4370984Z" />
        <Source Name="System.ServiceModel" />
        <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
        <Execution ProcessName="w3wp" ProcessID="3992" ThreadID="7" />
        <Channel />
        <Computer>TX-APP-J01</Computer>
    </System>
    <ApplicationData>
        <TraceData>
            <DataItem>
                <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
                    <TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
                    <Description>Throwing an exception.</Description>
                    <AppDomain>/LM/W3SVC/2/ROOT-1-130280558217413872</AppDomain>
                    <Exception>
                        <ExceptionType>System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                        <Message>An unexpected exception was encountered when using the WebContentTypeMapper.</Message>
                        <StackTrace>   at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.TryGetContentTypeMapping(String contentType, WebContentFormat&amp;amp; format)
   at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.IsContentTypeSupported(String contentType)
   at System.ServiceModel.Channels.HttpInput.ValidateContentType()
   at System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse()
   at System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage httpRequestMessage, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(AsyncCallback asynCallback, Object state)
   at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
   at System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state)
   at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
   at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
   at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
   at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
   at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
                        <ExceptionString>System.ServiceModel.CommunicationException: An unexpected exception was encountered when using the WebContentTypeMapper. ---&amp;gt; System.IO.IOException: The process cannot access the file 'c:\sapqueueservice\log.txt' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode)
   at SAPCallbackHandlerNamespace.RawContentTypeMapper.GetMessageFormatForContentType(String contentType)
   at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.TryGetContentTypeMapping(String contentType, WebContentFormat&amp;amp; format)
   --- End of inner exception stack trace ---</ExceptionString><InnerException><ExceptionType>System.IO.IOException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>The process cannot access the file 'c:\sapqueueservice\log.txt' because it is being used by another process.</Message><StackTrace>   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode)
   at SAPCallbackHandlerNamespace.RawContentTypeMapper.GetMessageFormatForContentType(String contentType)
   at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.TryGetContentTypeMapping(String contentType, WebContentFormat&amp;amp; format)</StackTrace><ExceptionString>System.IO.IOException: The process cannot access the file 'c:\sapqueueservice\log.txt' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode)
   at SAPCallbackHandlerNamespace.RawContentTypeMapper.GetMessageFormatForContentType(String contentType)
   at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.TryGetContentTypeMapping(String contentType, WebContentFormat&amp;amp; format)</ExceptionString>
                        </InnerException>
                    </Exception>
                </TraceRecord>
            </DataItem>
        </TraceData>
    </ApplicationData>
</E2ETraceEvent>

服务运行于:IIS 7.5、.NET 4.5、Windows Server 2008 R2

4

1 回答 1

0

这条消息很突出:

System.IO.IOException:该进程无法访问文件“c:\sapqueueservice\log.txt”,因为它正被另一个进程使用。

看起来有一个进程正在锁定这个文件。

尝试使用Process Explorer找出哪个进程有它的句柄。

于 2013-11-08T00:04:34.903 回答