当UI客户端退出时,WCF ServiceHost会抛出异常

时间:2013-06-12 11:37:00

标签: c# wcf service .net-4.0

我正在创建一个我在控制台应用程序中托管的服务。它包含一个从服务中获取数据的方法,以及一些可以在服务器上执行的方法。

为了测试服务,我创建了一个简单的WinForms应用程序,它连接到服务并调用主机上的操作。这似乎工作得很好,但是当我在配置文件中添加服务跟踪以查看发生了什么时,我注意到一旦关闭UI客户端就会在服务端抛出异常:

<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/nb-NO/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>WCF.Host.vshost.exe</AppDomain>
    <Exception>
        <ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
        <Message>
            An existing connection was forcibly closedby the remote host
        </Message>
        <StackTrace>   
            at System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted()   at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender, SocketAsyncEventArgs eventArgs)   at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)   at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
        </StackTrace>
        <ExceptionString>
            System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
        </ExceptionString>
        <NativeErrorCode>2746</NativeErrorCode>
    </Exception>
</TraceRecord>

(我已经在配置中添加了一个ConsoleTraceListener,以便我可以在出现警告时立即看到警告。)

当发生这种情况时,就我所知,它不会影响服务器端,在托管服务的控制台应用程序中不会抛出任何异常,如果我重新启动UI客户端,它很乐意让我执行针对主办。

即便如此,这是一个例外我非常想在主机端捕获,以便我能够处理它。在我看来,应该调查跟踪日志中的任何异常迹象,但我根本无法理解我在代码中可以捕获此错误的位置。通道上的封闭和故障事件似乎根本没有发生。

我在此VS 2012解决方案中重新创建了可以在此处下载的问题: http://db.tt/7l2Dnkpr(110 kB)

它由三个项目组成,一个带有服务定义的DLL,一个控制台主机和一个WinForms UI客户端。这复制了我在实际应用程序中的设置,但是这个测试要简单得多。该解决方案设置为启动多个项目,因此应该直接测试它。

WCF.Host应用程序创建一个正在侦听 net.tcp:// localhost:5000 / singleservice 的主机 在UI客户端中,单击“ GetObjects ”。这将创建servicehost的通道并在其上调用 GetObjects()方法。 现在,退出UI应用程序并注意控制台窗口中的跟踪输出。

任何人都可以看到为什么会发生这种情况,和/或我如何处理代码中的异常?

1 个答案:

答案 0 :(得分:1)

您在wcf客户端应用程序(WCF.ClientUI)中持有对服务对象的引用。因此,您必须在退出客户端进程之前关闭该频道。在客户端添加以下代码,关闭客户端应用程序时不会有任何异常。

    protected override void OnClosing(CancelEventArgs e)
    {
        base.OnClosing(e);
        ((IChannel)service).Close();
    }