复式 WCF + COM 对象的静态集合

发布于 2024-08-11 02:59:12 字数 2353 浏览 7 评论 0原文

我正在尝试构建一个 WCF 服务,该服务公开我没有原始源代码的特定 COM 对象的功能。我使用双工绑定,以便每个客户端都有自己的实例,因为每个特定实例都有绑定的事件,这些事件是通过回调(IAgent)传递的。似乎存在死锁或其他原因,因为在第一个操作之后,我的服务在第二个操作的锁定处阻塞。我尝试实现这些自定义 STA 属性和操作行为 (http://devlicio.us/blogs/scott_seely/archive/2009/07/17/calling-an-sta-com-object-from-a-wcf- operation.aspx),但我的OperationContext.Current始终为空。非常感谢任何建议。

服务

集合:

private static Dictionary<IAgent, COMAgent> agents = new Dictionary<IAgent, COMAgent>();

第一个操作:

    public void Login(LoginRequest request)
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            if (agents.ContainsKey(agent))
                throw new FaultException("You are already logged in.");
            else
            {
                ICOMClass startup = new ICOMClass();

                string server = ConfigurationManager.AppSettings["Server"];
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
                bool success = startup.Logon(server, port, request.Username, request.Password);

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log in." });

                COMAgent comAgent = new COMAgent { Connection = startup };
                comAgent.SomeEvent += new EventHandler<COMEventArgs>(comAgent_COMEvent);
                agents.Add(agent, comAgent);
            }
        }
    }

第二个操作:

    public void Logoff()
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            COMAgent comAgent = agents[agent];
            try
            {
                bool success = comAgent.Connection.Logoff();

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log off." });

                agents.Remove(agent);
            }
            catch (Exception exc)
            {
                throw new FaultException(exc.Message);
            }
        }
    }

I am trying to build a WCF service that exposes the functionality of a particular COM object that I do not have the original source for. I am using duplex binding so that each client has their own instance as there are events tied to each particular instance which are delivered through a callback (IAgent). It appears there is a deadlock or something because after the first action, my service blocks at my second action's lock. I have tried implementing these custom STA attribute and operation behaviors (http://devlicio.us/blogs/scott_seely/archive/2009/07/17/calling-an-sta-com-object-from-a-wcf-operation.aspx) but my OperationContext.Current is always null. Any advice is much appreciated.

Service

Collection:

private static Dictionary<IAgent, COMAgent> agents = new Dictionary<IAgent, COMAgent>();

First action:

    public void Login(LoginRequest request)
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            if (agents.ContainsKey(agent))
                throw new FaultException("You are already logged in.");
            else
            {
                ICOMClass startup = new ICOMClass();

                string server = ConfigurationManager.AppSettings["Server"];
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
                bool success = startup.Logon(server, port, request.Username, request.Password);

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log in." });

                COMAgent comAgent = new COMAgent { Connection = startup };
                comAgent.SomeEvent += new EventHandler<COMEventArgs>(comAgent_COMEvent);
                agents.Add(agent, comAgent);
            }
        }
    }

Second Action:

    public void Logoff()
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            COMAgent comAgent = agents[agent];
            try
            {
                bool success = comAgent.Connection.Logoff();

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log off." });

                agents.Remove(agent);
            }
            catch (Exception exc)
            {
                throw new FaultException(exc.Message);
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

染火枫林 2024-08-18 02:59:12

看一下这个非常相似的帖子:http:// www.netfxharmonics.com/2009/07/Accessing-WPF-Generate-Images-Via-WCF

您必须使用OperationContextScope才能从新生成的线程访问当前的OperationContext:

System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
    {
        using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
        {
            result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
        }
     }));

Take a look at this very similar post: http://www.netfxharmonics.com/2009/07/Accessing-WPF-Generated-Images-Via-WCF

You have to use an OperationContextScope to have access to the current OperationContext from the newly generated thread:

System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
    {
        using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
        {
            result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
        }
     }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文