简体   繁体   English

WCF服务回调类字段为空

[英]WCF Service Callback Class Fields Null

Over the last year I've learned a lot about WCF, but since I don't use it every day I still know enough to be dangerous. 在过去的一年中,我对WCF有了很多了解,但是由于我每天都不使用它,所以我仍然足够了解危险。 My example is too complicate to show something that will illustrate my full issue and I'll gladly show the pieces of what I do have that you would find helpful. 我的示例过于复杂,无法显示出可以说明我的完整问题的东西,并且我很乐意显示我所拥有的东西,这些东西对您会有所帮助。 I have a duplex service and built a class called HostedTransactionServiceProcess that encapsulates the service calls so that any client-level class using this doesn't have to understand the intricacies of working with a WCF Service. 我有一个双工服务,并建立了一个称为HostedTransactionServiceProcess的类,该类封装了服务调用,因此使用该类的任何客户端级别的类都不必了解使用WCF服务的复杂性。 The service that it is encapsulating its calls to can also communicate back via callback events. 封装其调用的服务也可以通过回调事件进行通讯。 The problem tends to be the coordination between service operations and receiving callback events. 问题往往是服务操作与接收回调事件之间的协调。 Whenever a callback event is called by the service, the class-level property/field values for HostedTransactionServiceProcess is null. 每当服务调用回调事件时,HostedTransactionServiceProcess的类级别属性/字段值都为null。 I think this makes sense as creating the channel/proxy from Service-to-Client is left to the Service and doesn't allow for as much of the control we have when creating a channel/proxy communicating from Client-to-Service. 我认为这是有道理的,因为从服务到客户端的创建通道/代理留给服务,并且在创建从客户端到服务的通信通道/代理时并没有我们所拥有的控制权。 So if it instantiates its callback proxy, then everything defaults and its as though those values were never modified. 因此,如果实例化其回调代理,则所有内容均为默认值,就好像这些值从未被修改过一样。

First of all, is this correct? 首先,这是正确的吗? Secondly, how do I work around it? 其次,我该如何解决?

I was able to work around a need to utilize an EventWaitHandle by creating a named one that can work inter-process, but I still need other properties/field data in the class to be seen between operation calls and callback event calls. 通过创建可以在进程间工作的命名对象,我能够解决使用EventWaitHandle的需要,但是我仍然需要类中的其他属性/字段数据才能在操作调用和回调事件调用之间看到。

Again, I can give more info as needed, just let me know! 同样,我可以根据需要提供更多信息,请告诉我!

Edit: I tried to simplify things into an un-workable class that should at least illustrate my issue. 编辑:我试图将事情简化为一个不可行的类,至少应该说明我的问题。 Maybe this will help? 也许这会有所帮助吗?

 [CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = true)]
public class HostedTransactionServiceProcess : ServiceProcess<IHostedTransactionService, HostedTransactionServiceInvoker, ConfigurationDuplexChannelFactory<IHostedTransactionService>>, IHostedTransactionServiceProcess, IHostedTransactionCallbackService
{
    #region Properties

    private ICADSession _cadSession;

    public ICADSession CADSession
    {
        get { return _cadSession; }
        set { _cadSession = value; }
    }


    #endregion
    #region Operations

    public void Commit(ICADSession cadSession, IEnumerable<IDTOEntity> dtoEntityCollection, IDTODocument dtoDocument, IDTOOperationLock operationLock)
    {

        lock (_serviceInvokerLock)
        {
            //Since the callback session will be instantiated by the WCF Service, any fields/properties in this class will be instantiated to null.
            //This is because the Service is instantiating its own instance, creating its own proxy, based on the applied callback interface contract
            //To work around this so that a call to the CAD System can wait until the CAD System responds back through the WCF Service, a named, inter-process
            //EventWaitHandle will be used
            using (EventWaitHandle waitHandle = ServiceWaitHandleHelper.StartNew(false, EventResetMode.AutoReset, cadSession, "Commit"))
            {
                //Set a local value... the issue is that this will end up null when the callback event is called!!!!!
                //This seems to be because this instance making the Commit() call is different from the callback instance created to make the OnCommitted() call!!!
                this.CADSession = cadSession;

                //Make the proxy operation call
                this.ServiceInvoker.Execute(serviceProxy => serviceProxy.Commit(cadSession, dtoEntityCollection, dtoDocument, operationLock));

                //The lock will not be released for the next Commit() operation call until the entire commit process is completed or the operation times out.
                waitHandle.WaitOne(TimeSpan.FromMilliseconds(MAX_OPERATION_TIMEOUT));

            }
        }
    }

    //The WCF Service Callback will call this
    public void OnCommitted(ICADSession cadSession, IEnumerable<IDTOEntity> entityCollection, IDTODocument dtoDocument, IDTOOperationLock operationLock)
    {
        //First allow the Commit() operation to continue
        EventWaitHandle waitHandle = ServiceWaitHandleHelper.GetExisting(cadSession, "Commit");
        if (waitHandle != null && this.CADSession == cadSession)  //!!!!!! Here is the issue!!!  Even though this.CADSession was set to a value, the callback instance says it is null!!!
            waitHandle.Set();
        else
            return;
    }

    #endregion
}

I guess I've answered my own question. 我想我已经回答了我自己的问题。 I basically have the service and two clients. 我基本上有服务和两个客户。 The callback event seemed to be getting called, but the field values were null. 回调事件似乎正在被调用,但是字段值是null。 When debugging I verified that it was subscribing the callback, so it ws driving me nuts. 调试时,我验证了它正在订阅回调,因此它使我发疯。 Then I discovered that the callback for one client was getting called, but not the other and it turns out though it captured the callback channel, it was making the callback before the previous method was finished while on the same thread... deadlock... So I started my connection and registration to the event on a separate thread than the operation call that initiates this process and now it seems to work. 然后我发现一个客户端的回调被调用,而另一个客户端没有被调用,事实证明,尽管它捕获了回调通道,但它是在同一线程上死锁的情况下,在前一个方法完成之前进行了回调。因此,我在与启动该过程的操作调用不同的线程上开始了对事件的连接和注册,现在看来它可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM