WCF:如何在正常关闭连接的同时发送数据?

maf*_*afu 0 wcf

我有一个提供Login方法的WCF服务.客户端需要调用此方法(因为它是唯一的IsInitiating = true).在任何情况下,此方法都应返回一个描述调用成功的字符串.如果登录失败,则应关闭连接.

问题在于收盘时间.我想发送返回值,然后立即关闭连接.

string Login (string name, string pass)
{
    if (name != pass) {
        OperationContext.Current.Channel.Close ();
        return "fail";
    }
    else {
        return "yay";
    }
}
Run Code Online (Sandbox Code Playgroud)

MSDN指出,呼吁Close在通道上

导致ICommunicationObject从Opened状态正常转换为Closed状态.Close方法允许在返回之前完成任何未完成的工作.例如,完成发送任何缓冲的消息).

这对我来说不起作用(或者我的理解是错误的),因为close立即执行--WCF不等待Login方法完成执行并返回字符串但是先关闭连接.

因此,我假设调用Close不会等待运行方法完成.现在,我怎么还能返回一个值,然后关闭?

在我的绝望中,我尝试了以下,但这不是一个严肃的解决方案.

new Thread (() => {
    Thread.Sleep (100);
    OperationContext.Current.Channel.Close ();
}).Start ();
Run Code Online (Sandbox Code Playgroud)

Aar*_*ght 6

当文档说"优雅"时,它实际上是在谈论ICommunicationObject.Close客户端调用时.在服务方面,如果您在客户端仍在等待响应时尝试关闭通道,那么您将度过糟糕的时光.

客户端会感到困惑,不必费心确认关闭,然后服务器将超时Close尝试,在您的情况下,工作线程正在发生,工作线程上未处理的异常不利于您的服务健康或您自己的理智.

你真正想要的不是一个优雅的连接关闭,你想要强行断开无法成功登录的客户端.为此,您必须在发送响应注册操作完成时的事件处理程序:

public string Login(string name, string pass)
{
    if (name != pass)
    {
        OperationContext.Current.OperationCompleted += LoginFailed;
        return "fail";
    }
    return "yay";
}

private void LoginFailed(object sender, EventArgs e)
{
    OperationContext.Current.Channel.Abort();
}
Run Code Online (Sandbox Code Playgroud)

这将做我非常确定你想做的事情 - 将"失败"发送回客户端,清理所有需要清理的东西,然后断开客户端连接,防止会话中的任何进一步活动.

顺便说一下,我不知道这与真实的服务代码有多接近,但是当你可以使用WCF的内置服务凭证系统时,在服务上使用"Login"方法有点多余.