回调干扰初始呼叫的返回

时间:2012-10-23 08:44:03

标签: c# wcf callback

我有一个WCF服务,我正在尝试让回调工作。

Interface类看起来像:

[ServiceContract(
    SessionMode = SessionMode.Required,
    CallbackContract = typeof(IPredatorEngineCallback))]
public interface IMyApplication
{
    [OperationContract]
    Boolean DoSomething(string mystring);

    [OperationContract]
    Boolean SubscribeToEvent();

}

public interface IMyApplicationCallback
{
    [OperationContract (IsOneWay = true)]
    void EventRaised(EventMessage myEventMessage)
}

EventMessage是服务器和服务器共享的通信库中的类。客户端。

此界面的实现如下:

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class MyApplication : IMyApplication
{
    private List<IMyApplicationCallback> CallbackList = new List<IMyApplicationCallback>;

    public Boolean DoSomething(string mystring)
    {
           // Do stuff

           // Now Raise an event
           PublishEvent();

           return true;
    }

    public Boolean SubscribeToEvent()
    {    
        IMyApplicationCallback IMAC = OperationContext.Current.GetCallbackChannel<IMyApplicationCallback>();
        if (!Callbacklist.Contains(IMAC)
           Callbacklist.Add(IMAC);
    }

    private void PublishEvent()
    {
        EventMessage myEM = new EventMessage();

        // Populate myEM.Fields

        Callbacklist.ForEach(delegate(IMyApplicationCallback callback)
        { callback.EventRaised(myEM); });
    }
}

客户可以选择订阅接收活动。

我分阶段构建我的应用程序,并且在实现回调之前,服务工作正常。对DoSomething()的调用会执行他们应该执行的操作并立即返回。

现在我已经实现了CallBacks,如果我在DoSomething中注释掉RaiseEvents()行,它会立即返回。

我的客户端代码现在首先调用SubscribeToEvent(),然后再次调用DoSomething()。

如果我取消注释并继续使用调试器,我会发现DoSomething很快就完成了 - 没有延迟。我有客户端和与VS2010在同一台机器上运行的WCF服务。我在DoSomething()中跟进它。

但是,我的客户端中的回调函数未被调用。 1分钟后,它终于被调用了,我还收到一条错误消息,说明我的原始呼叫已经超时。所以我将app.config更改为10秒,错误消息为:

"This request operation sent to http://localhost:8732/Design_Time_Addresses/MyApplication/MyAppication did not receive a reply in the configured timeout (00:00:09.987997). The time allotted to this operation may have been a portion of a longer timeout..."

所以看来有些东西阻止了第一次通话的回归;但事件已经提出,因为它最终到达那里。我怀疑这与锁定/并发模式有关,但我承认我已经失去了解决方案。

在客户端,我使用了通过添加服务引用生成的代理代码。

服务器端app.config(仅限相关部分):                                        
                                                    
         

                                                                                                                                                                                                                         

</configuration>

客户端App.config:

<configuration>
<system.serviceModel>
    <bindings>
        <wsDualHttpBinding>
            <binding name="WSDualHttpBinding_IPredatorEngine" closeTimeout="00:00:10"
                openTimeout="00:00:10" receiveTimeout="00:10:00" sendTimeout="00:00:10"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                <security mode="Message">
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" />
                </security>
            </binding>
        </wsDualHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8732/Design_Time_Addresses/MyApplication/MyApplication/"
            binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IMyApplication"
            contract="MyApplication.IMyApplication" name="WSDualHttpBinding_IMyApplication">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>
</configuration>

我认为我没有配置正确的东西。有谁能发现它?

1 个答案:

答案 0 :(得分:0)

经过大量搜索和反复试验,我发现我需要将SynchronizationContext设置为false。

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext=false)]

我还需要在客户端代码的实现上设置以下内容:

[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext = false)]