WCF方法不返回

时间:2015-09-09 09:24:53

标签: c# wcf

我对WCF服务有一个奇怪的问题,我无法解决。 当我在我的服务上调用特定方法时,它只是在绑定超时之前不会返回到客户端,尽管它已经在服务器上返回并且已经向客户端发送了返回消息。

我在客户端使用ChannelFactory<T>,并且共享接口定义如下:

[ServiceContract]
interface IService {
    [OperationContract] bool Upload(Guid id, string name, byte[] data);
    [OperationContract] bool Unlock(Guid id);
}

[ServiceContract(Name = "IService")]
interface IServiceAsync : IService {
    [OperationContract] Task<bool> UploadAsync(Guid id, string name, byte[] data);
    [OperationContract] Task<bool> UnlockAsync(Guid id);
}

IService接口由服务器类实现,IServiceAsync接口仅在客户端上使用(并自动工作)。 服务器使用ServiceHost在独立控制台应用程序中实现,服务器类如下所示:

[ServiceBehavior(InstanceContextMode = Single, ConcurrencyMode = Multiple)]
static class Server : IService {
    public bool Upload(Guid id, string name, byte[] data) { ... }
    public bool Unlock(Guid id) { ... }
}

在客户端,我使用ChannelFactory<T>创建一个频道,如下所示:

static IServiceAsync GetService() {
    EndpointAddress endpoint = new EndpointAddress(/* some Uri */);
    NetTcpBinding binding = /* NetTcpBinding without security */;

    ChannelFactory<IServiceAsync> factory =
            new ChannelFactory<IServiceAsync>(binding, endpoint);
    factory.Open();
    IServiceAsync proxy = factory.CreateChannel();
    ((IServiceChannel)proxy).Open();
    return proxy;
}

在我的场景中,我然后将一些文件上传到服务器,这个操作可以随时由用户取消。上传代码如下所示:

static async void UseService(IServiceAsync proxy) {
    try {
        byte[] buffer;
        do {
            cancellationToken.ThrowIfCancellationRequested();
            buffer = GetBytes();
            bool uploaded = await proxy.UploadAsync(id, name, buffer);
        } while(buffer.Length > 0);
        ((IClientChannel)proxy).Close();
    }
    catch (Exception ex) {
        try {
            proxy.Unlock(id);
        }
        catch {
            // Connection may have failed
        }
        throw;
    }
}

现在上传完成后一切正常,但是当上传被取消,cancellationToken.ThrowIfCancellationRequested()引发异常时,我想解锁服务器。
所以我调用proxy.Unlock(id),它在服务器上被调用,返回那里(通过在服务器上return true;之前写入控制台确认),但是在绑定超时之前不会在客户端返回

我查看了一次网络流量并确认实际上有一条返回消息发送给客户端。 (我实际上并不知道proxy.Unlock(id)是返回还是抛出CommunicationException,我怀疑是第二个。)

TL; DR:虽然WCF方法已在服务器端返回,但客户端没有返回WCF方法,其他方法工作正常。

所以,如果你仍然在那个文本墙之后仍然在这里:这里有什么问题? 我该如何调试或解决这个问题? 如果您需要更多信息,请告诉我。

更新

感谢Daniel的评论,我做了一些跟踪,并成功地重现了这个问题。

在等待异步WCF方法时使用ConfigureAwait(false)时会出现问题,抛出异常,并且在下次调用WCF方法之前没有上下文切换。我在GitHub上传了一个小test project

这可能是WCF代理中自动实现的异步方法中的错误吗?

0 个答案:

没有答案