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 客户端,它会很高兴地让我对主机执行操作。

即便如此,这是一个我非常想在主机端捕获的异常,以便我可以处理它。在我看来,应该调查跟踪日志中的任何异常迹象,但我根本不明白在我的代码中哪里可以捕捉到这个错误。通道上的 Closed 和 Faulted 事件似乎根本没有触发。

我在这个 VS 2012 解决方案中重新创建了问题,可以在这里下载:http: //db.tt/7l2Dnkpr (1​​10 kB)

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

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

谁能看到发生这种情况的原因,和/或我如何处理代码中的异常?

4

1 回答 1

1

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

    protected override void OnClosing(CancelEventArgs e)
    {
        base.OnClosing(e);
        ((IChannel)service).Close();
    }
于 2013-06-12T12:00:12.403 回答